Unity3d-在另一个脚本中定义事件

问题描述:

假设我想向下拉元素的OnSelect()事件添加功能.

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

通常我只是将新脚本添加到特定的下拉gameObject中:

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

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.

问题:是否可以在另一个脚本中定义功能? 例如.我有一个脚本附加到主父菜单"Menue",在其中引用此特定的下拉游戏对象.

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.

如何在另一个脚本中定义OnSelect?

How can I define the OnSelect inside another script?

PS:这是问这个问题的正确地方,还是我应该在游戏开发上问这个问题?

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

使用事件和委托.如果您是新手,可以在此处中找到简化的教程.

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

应该是这样的:

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

将其添加到您的LanguageDropdown脚本中,您应该得到以下信息:

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);
        }
    }
}

现在,您可以分别从另一个脚本的OnEnableOnDisable函数脚本中订阅和取消订阅该事件:

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");
}

基本上我想知道是否被迫附加了脚本 LanguageDropdown到游戏对象,或者如果不需要,我 可以通过未附加到该脚本的另一个脚本来设置所有内容 具体下拉菜单.

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.

否,您可以使用EventTrigger类注册如下所示的事件,而不必将其附加到每个对象上:

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.