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

Bla*_*ack 1 c# unity-game-engine

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

通常我只会向特定的下拉游戏对象添加一个新脚本:

下拉脚本

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");
    }
}
Run Code Online (Sandbox Code Playgroud)

提示:如果选择了下拉菜单,脚本只会输出一条消息。


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

如何定义OnSelect另一个脚本内部?

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

Pro*_*mer 5

使用事件和委托。如果您不熟悉,可以在此处找到相关的简化教程。

它应该是这样的:

public delegate void SelectAction(GameObject target);
public static event SelectAction OnSelectedEvent;
Run Code Online (Sandbox Code Playgroud)

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

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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");
}
Run Code Online (Sandbox Code Playgroud)

基本上我想知道我是否被迫将脚本 LanguageDropdown 附加到游戏对象,或者如果这不是必需的,我可以从另一个未附加到该特定下拉列表的脚本中设置所有内容。

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

EventTrigger.Entry entry = new EventTrigger.Entry();
entry.eventID = EventTriggerType.Select;
entry.callback.AddListener((eventData) => { SelectAction(); });
Run Code Online (Sandbox Code Playgroud)

请不要使用它。它很慢,我也从很多人那里验证了这一点。