1

Let's say I would like to add functionality to the OnSelect() Event of a dropdown element.

Normally I would just add a new script to the specific dropdown gameObject:

Dropdown script

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class LanguageDropdown : MonoBehaviour, ISelectHandler// required interface when using the OnSelect method.
{
    //Do this when the selectable UI object is selected.
    public void OnSelect(BaseEventData eventData)
    {
        Debug.Log(this.gameObject.name + " was selected");
    }
}

Hint: The script simply outputs a message if the Dropdown is getting selected.


Question: Is it possible to define the functionality inside another script? E.g. I have a script attached to the master parent "Menue" where I am referencing this specific dropdown gameobject.

How can I define the OnSelect inside another script?

PS: Is this the correct place to ask this question, or should I ask it on gamedevelopement instead?

3
  • 1
    @Programmer, I think your comment landed in the wrong section ;) Commented Oct 31, 2017 at 17:14
  • 1
    lol that's right. That was made for Ed Marty's answer that uses UnityEvent and I was in a hurry. I think he saw that. Commented Nov 1, 2017 at 0:09
  • Worrying about speed in a user interaction event is definitely premature optimization. If performance is not an issue, making the code simple and readable trumps making it efficient (as long as it's not a bad design). Commented Nov 2, 2017 at 22:05

3 Answers 3

5

Use event and delegate. You can find a simplified tutorial for that here if this is new to you.

It should be something like this:

public delegate void SelectAction(GameObject target);
public static event SelectAction OnSelectedEvent;

Add that to your LanguageDropdown script and you should get this:

public class LanguageDropdown : MonoBehaviour, ISelectHandler// required interface when using the OnSelect method.
{
    public delegate void SelectAction(GameObject target);
    public static event SelectAction OnSelectedEvent;

    //Do this when the selectable UI object is selected.
    public void OnSelect(BaseEventData eventData)
    {
        Debug.Log(this.gameObject.name + " was selected");

        //Invoke Event
        if (OnSelectedEvent != null)
        {
            OnSelectedEvent(this.gameObject);
        }
    }
}

Now, you can subscribe and un-subscribe to the event in the OnEnable and OnDisable functions respectively script from another script:

void OnEnable()
{
    //subscribe to event
    LanguageDropdown.OnSelectedEvent += SelectAction;
}

void OnDisable()
{
    //Un-subscribe to event
    LanguageDropdown.OnSelectedEvent -= SelectAction;
}

//This will be called when invoked
void SelectAction(GameObject target)
{
    Debug.Log(target.name + " was selected");
}

Basically I wanted to know if I am forced to attach the script LanguageDropdown to the gameobject, or If this is not required and I can setup everything from another script which is not attached to that specific dropdown.

No, you can use the EventTrigger class to register the events like below and you won't have to attach it to each object:

EventTrigger.Entry entry = new EventTrigger.Entry();
entry.eventID = EventTriggerType.Select;
entry.callback.AddListener((eventData) => { SelectAction(); });

Please, do not use that. It is slow and I have verified this from multiple people too.

Sign up to request clarification or add additional context in comments.

1 Comment

I think I was not clear in my question. Basically I wanted to know if I am forced to attach the script LanguageDropdown to the dropdown gameobject, or If this is not required and I can setup everything from another script which is not attached to that specific dropdown, by just referencing to the dropdown gameobject from that script.
3

A Unity-centric solution would be to use a UnityEvent which lets you make these changes in the inspector.

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class LanguageDropdown : MonoBehaviour, ISelectHandler// required interface when using the OnSelect method.
{
    public UnityEvent Selected;

    //Do this when the selectable UI object is selected.
    public void OnSelect(BaseEventData eventData)
    {
        Debug.Log(this.gameObject.name + " was selected");
        Selected.Invoke();
    }
}

Then the LanguageDropdown component will have a Selected member visible in the inspector to which you can then assign an Object and method target (much like a Button).

Component with *Selected()* member visible

Note: You can change UnityEvent to UnityEvent<LanguageDropdown> if you want to include the source object:

public class LanguageDropdown : MonoBehaviour, ISelectHandler// required interface when using the OnSelect method.
{
    public UnityEvent<LanguageDropdown> Selected;

    //Do this when the selectable UI object is selected.
    public void OnSelect(BaseEventData eventData)
    {
        Debug.Log(this.gameObject.name + " was selected");
        Selected.Invoke(this);
    }
}

The target method must then have the correct parameter list

(i.e. public void method(LanguageDropdown dropdown) )

Comments

1

You can define public method in another script, and call it int OnSelect() implementation.

For example:

public interface IDropdownContext
{
    void OnDropdownSelected(BaseEventData eventData);
}

public class Test : MonoBehaviour, IDropdownContext
{

    public void OnDropdownSelected(BaseEventData eventData)
    {
        Debug.Log("OnDropdownSelected");
    }
}


public class LanguageDropdown : MonoBehaviour, ISelectHandler// required interface when using the OnSelect method.
{
    [SerializeField]
    public Test context;

    //Do this when the selectable UI object is selected.
    public void OnSelect(BaseEventData eventData)
    {
        Debug.Log(this.gameObject.name + " was selected");

        context.OnDropdownSelected(eventData);
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.