Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

UI Doesn't Accept Functions with more than two Arguments or Arrays?

Discussion in 'UGUI & TextMesh Pro' started by kenaochreous, Mar 4, 2015.

  1. kenaochreous

    kenaochreous

    Joined:
    Sep 7, 2012
    Posts:
    395
    I'm confused, I was able to get my button to work with a function with one argument. But when I add a second argument or an Array I could no longer find the function. What gives?

    Code (CSharp):
    1. Public Void ExampleA(int someIntC){
    2. //Able to find ExampleA
    3. }
    4. Public Void ExampleB(int someIntC,int someIntD){
    5. // Not Able to find ExampleB
    6. }
    7. Public Void ExampleC(int[] someInts){
    8. // Not Able to find ExampleC
    9. }
     
    MilenaRocha likes this.
  2. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    The inspector only lets you assign callback functions that take zero or one arguments, and there are only a few allowed types for the argument (bool, int, float, and GameObject, I think).

    But you can always write a wrapper function that calls your main function with whatever arguments you like.

    If you're feeling overly constrained by Unity's event system, you can also write your own C# events with any method signature you like--but the inspector doesn't support them, so you'll have to assign the listeners in code.
     
    rakkarage likes this.
  3. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,688
    The property drawer only supports a single parameter unfortunately.

    If you bind it through code you should be able to use multiple parameters in the signature.

    The event is based off UnityEvents and UnityActions, so up to 4 parameters are supported but only using c#base types (doesn't include arrays) If you want to make your own custom event type, then I would implement using these to keep conformity with the UI system.
     
  4. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    Are there advantages to using Unity's event system other than access to the property drawer?
     
  5. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,688
    Only in so much as you can craft your events how you like or prefer them but the properties are still limited to Base C# data types and Unity objects.

    The new event system does have one big advantage, that is uses a clever weak referencing system under the hood which is more efficient and safe than fixed references and the ghastly SendMessage
     
  6. Dameon_

    Dameon_

    Joined:
    Apr 11, 2014
    Posts:
    542
    Isn't System.object one of the arguments you can pass? If so, then you just pass a custom class with as many fields as you want to have arguments.
     
  7. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,688
    @Dameon_ You can try it but all my tests seems to be inline with what was said at Unite on the new UI.
     
  8. tapticc

    tapticc

    Joined:
    Jan 16, 2014
    Posts:
    379
    I had a more simplistic approach to this, no doubt to be frowned upon but it worked for me!

    I called 2 functions on the gameobject in the OnValueChanged section; the first call passes a string variable and sets this in the class instance, and the second call passes in a slider instance. I can then use the previously set string name and the slider value in the second call's function.
     
  9. ebubeud1996

    ebubeud1996

    Joined:
    Mar 31, 2018
    Posts:
    6
    If you want to pass multiple parameters in a function, you can pass them as a single string, separating the values with a comma ",".
    For example, if you want to pass in 2, 3,4 in a single function, do it this way:

    In the Unity Editor, Set the Params for the function:
    test("2,3,4")

    //in your c# script
    public void test(string params){
    //split the params
    string[] splittedParams = params.Split(',');

    //get the first param
    string FirstParam = splittedParams[0];

    //Convert it back to int
    int firstParam = int.Parse(FirstParam);

    Debug.Log(firstParam);
    //2
    }
     
  10. junedmmn

    junedmmn

    Joined:
    Dec 19, 2016
    Posts:
    15
    This isn't the answer, what if I want to pass GameObjects such as which Button Pressed etc? or What if I want to pass Objects of Different types other than basic ints or strings.
     
    Last edited: Nov 28, 2018
  11. snoche

    snoche

    Joined:
    Feb 22, 2010
    Posts:
    82
    I am looking for the same, for instance I want to pass a text UI button and a Gameobject reference, how I can achieve that?
     
  12. Shanmf3d

    Shanmf3d

    Joined:
    Aug 1, 2017
    Posts:
    8
    I had the same approach to @ebubeud1996, I guess it will just take a bit of engineering to find a possible solution, but I don't think it would be impossible. This might not be the solution you want to use, but you could have a reference to the objects that you want to trigger from the script, like a list of UI buttons and a list of GameObjects.

    Then you can pass a string into the button that gets split then you can do a a string comparision to find the reference gameobject and ui button, then run the command. There might be better ways of doing this.
     
    Last edited: Apr 4, 2019
  13. drewd145

    drewd145

    Joined:
    Apr 11, 2019
    Posts:
    1
    My workaround for this was to create a function with the button itself as the parameter. Add a script component to the button and then you should be able to access any number of parameters in your function through btn.GetComponent<MyScript>()
     
  14. nickmeier

    nickmeier

    Joined:
    Jul 4, 2015
    Posts:
    1
    My solution is to create a new serializable scriptable object to hold the arguments.
    Code (CSharp):
    1. [CreateAssetMenu(fileName = "Game Config", menuName = "GameConfig", order = 0)]
    2. [Serializable]
    3. public class GameConfig : ScriptableObject {
    4.     public Environment environment;
    5.     public Loadout playerLoadout;
    6.     public Loadout opponentLoadout;
    7.     public bool spectating;
    8. }
     
    romelianism and MilenaRocha like this.
  15. nackerboss06

    nackerboss06

    Joined:
    Jun 4, 2021
    Posts:
    13
    well my method is very stupid but might help someone is just use other function for example:
    private int argument_1;
    public void readValue(int first argument)
    {
    argument_1= value
    }
    public void req2arguments(int other_argument)
    {
    something.set_something_that_require_two_argument(argument_1, other_argument)
    }
    and add two unity event and assign the readValue first and req2arguments second
    i know it weakness is you need a lot of readValue for more input you want but i don't find any solution for this