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

C# Unity3d-在另一个脚本中定义事件,c#,unity3d,C#,Unity3d,假设我想向下拉元素的OnSelect()事件添加功能 通常我只会在特定的下拉游戏对象中添加一个新脚本: 提示:如果下拉菜单被选中,脚本只输出一条消息 问题:是否可以在另一个脚本中定义功能? 例如,我有一个脚本附加到主父“菜单”,在这里我引用这个特定的下拉游戏对象 如何在另一个脚本中定义OnSelect PS:这是问这个问题的正确地方,还是我应该在GameDevelopment上问它?您可以在另一个脚本中定义public方法,并将其称为intOnSelect()实现 例如: public in

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

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

提示:如果下拉菜单被选中,脚本只输出一条消息


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

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


PS:这是问这个问题的正确地方,还是我应该在GameDevelopment上问它?

您可以在另一个脚本中定义public方法,并将其称为int
OnSelect()
实现

例如:

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

您可以在另一个脚本中定义public方法,并将其称为int
OnSelect()
implementation

例如:

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

使用事件和委托。如果这对你来说是新的,你可以找到一个简化的教程

应该是这样的:

public delegate void SelectAction(GameObject target);
public static event SelectAction OnSelectedEvent;
将其添加到您的
language下拉列表中,您将得到以下结果:

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);
        }
    }
}
现在,您可以在另一个脚本的
oneable
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");
}
基本上我想知道我是否被迫附加脚本 语言下拉到游戏对象,或者如果这不是必需的,我 可以从未附加到该脚本的其他脚本设置所有内容 特定下拉列表

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

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

请不要用那个。这是缓慢的,我已经验证了这一点,从多人太多

使用事件和委托。如果这对你来说是新的,你可以找到一个简化的教程

应该是这样的:

public delegate void SelectAction(GameObject target);
public static event SelectAction OnSelectedEvent;
将其添加到您的
language下拉列表中,您将得到以下结果:

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);
        }
    }
}
现在,您可以在另一个脚本的
oneable
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");
}
基本上我想知道我是否被迫附加脚本 语言下拉到游戏对象,或者如果这不是必需的,我 可以从未附加到该脚本的其他脚本设置所有内容 特定下拉列表

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

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

请不要用那个。这是缓慢的,我已经验证了这一点,从多人太多

以统一为中心的解决方案是使用
UnityEvent
,它允许您在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();
    }
}
然后,
language下拉列表
组件将在inspector中显示一个选中的成员,然后您可以为其分配一个对象和方法目标(很像一个按钮)

注意:如果要包括源对象,可以将
UnityEvent
更改为
UnityEvent

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);
    }
}
public class language下拉列表:MonoBehavior,ISelectHandler//使用OnSelect方法时需要接口。
{
选择公共单位事件;
//选择可选择的UI对象时执行此操作。
public void OnSelect(BaseEventData eventData)
{
Debug.Log(已选择this.gameObject.name+);
选中。调用(此);
}
}
然后,目标方法必须具有正确的参数列表


(即
公共作废方法(LanguageDropdown)

以统一为中心的解决方案是使用
UnityEvent
,它允许您在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();
    }
}
然后,
language下拉列表
组件将在inspector中显示一个选中的成员,然后您可以为其分配一个对象和方法目标(很像一个按钮)

注意:如果要包括源对象,可以将
UnityEvent
更改为
UnityEvent

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);
    }
}
public class language下拉列表:MonoBehavior,ISelectHandler//使用OnSelect方法时需要接口。
{
选择公共单位事件;
//选择可选择的UI对象时执行此操作。
public void OnSelect(BaseEventData eventData)
{
Debug.Log(已选择this.gameObject.name+);
选中。调用(此);
}
}
然后,目标方法必须具有正确的参数列表


(例如,
公共作废方法(LanguageDropdown)

我想我的问题不清楚。基本上,我想知道我是否被迫将脚本
LanguageDropdown
附加到dropdown游戏对象,或者这不是必需的,我可以通过引用该脚本中的dropdown游戏对象,从另一个未附加到该特定dropdown的脚本设置所有内容。我想我的问题还不清楚。基本上,我想知道我是否被迫将脚本
LanguageDropdown
附加到dropdown游戏对象,或者这不是必需的,我可以通过引用该脚本中的dropdown游戏对象,从另一个未附加到该特定dropdown的脚本设置所有内容。@Programmer,我认为你的评论放错了地方;)哈哈,没错。这是为使用
UnityEvent
的用户的答案而做的,我当时很匆忙。我想他看到了。担心用户交互事件的速度肯定是过早的优化。如果性能不是问题,那么让代码简单易读胜过提高效率(只要它不是一个糟糕的设计)。@Programmer,我认为你的评论放错了地方;)哈哈,没错。这是为使用
UnityEvent
的用户的答案而做的,我当时很匆忙。我想他看到了。担心汽车的速度