0
\$\begingroup\$

I have the following public method in a MonoBehaviour attached to a game object in my scene:

public void ButtonZapuskk(int t, int a, int b, int i)
{
    Text[t].SetActive(true);
    Images[i].SetActive(true);
    ButtonBuy[b].SetActive(true);
    ButtonActiv[a].SetActive(true);
}

I want to call this function when the player clicks a UI button, but it does not show up as a function I can call from the On Click event.

Why doesn't this function show up, and how can I fix it?

\$\endgroup\$
1
  • \$\begingroup\$ Please formulate the question in englisch. The editor won't as well display functions with multiple parameters out of the box \$\endgroup\$ Commented Sep 15, 2024 at 14:04

1 Answer 1

1
\$\begingroup\$

A method will only show up for selection in the event's menu if it's public and one of the following is true:

  • It takes no parameters (eg. public void DoThing() {...)

  • It takes only one parameter, of a primitive type (like bool, int, float, string...)

  • It takes only one parameter, of a type that derives from UnityEngine.Object (like GameObject, Component, ScriptableObject, or asset types like Material...)

A method with 2+ parameters will never show up in this menu. Neither will one with a parameter that's a custom serializable class, struct, or enum, unfortunately.

So here's how I might set this up instead (taking some guesses at what you're using it for)...

public class ButtonManager : MonoBehaviour {

    // Use this structure to store everything you want
    // to modify for a given button click event.
    [System.Serializable]
    public struct ButtonAction {
        public string name;
        public TextMeshProUGUI textToShow;
        public Image imageToShow;
        public Button buyButton;
        public Button activateButton;
    }

    // Array of the structs above, to store
    // our library of button actions.
    [SerializeField]
    ButtonAction[] _actions;

    // Our button click handler now only needs a single parameter.
    public void DoAction(string actionName) {
        // Find matching action in our array, and report error if we can't find it.
        int index = System.Array.FindIndex(
            _actions, 
            (a) => System.String.Equals(a.name, actionName, System.StringComparison.OrdinalIgnoreCase)
        );
        if (index < 0) {
            Debug.LogError($"Could not find button action named {actionName}.");
            return;
        }

        // If we get here, we found a matching action in our library.
        // Do the necessary actions on its various members.
        var action = _actions[index];
        action.textToShow.gameObject.SetActive(true);        
        action.imageToShow.gameObject.SetActive(true);        
        action.buyButton.gameObject.SetActive(true);        
        action.activateButton.gameObject.SetActive(true);
    }
}

This gives you an expandable list in the inspector that you can use to associate your text/image/button references to a specific "action", keyed by a name (helpfully displayed in the fold-out's collapsed state):

Button Manager inspector

And because our DoAction(string actionName) takes only one parameter and it's a primitive type, we can select it from a UnityEvent in the inspector:

Event handler wired up in OnClick event inspector

You could look up the button action by its index instead of by name, but I think using the name here is more legible to the designer setting this up, so it's easier to understand how it should work, spot bugs, etc.

I'm usually not a fan of "stringly typed" code, but here I'd argue it's no more error prone than needing to provide 1-4 magic number indices to a function. Searching through the list doing string comparisons is not the fastest, but this is code that will run at most once per frame, only when the player clicks, and iterates a list that's probably no more than a few dozen entries long, so this is not the place to micro-optimize. Especially not at the cost of clarity for the developers wiring up these menus.

I'd also question whether you need separate text/image/button objects for each item these buttons can turn on/off, or if it would suffice to have one "template" object set up that you populate with new strings/sprites/etc. when a new item is selected.

\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.