代码之家  ›  专栏  ›  技术社区  ›  Black

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

  •  1
  • Black  · 技术社区  · 7 年前

    OnSelect() 下拉元素的事件。

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

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

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


    问题 :是否可以在另一个脚本中定义功能?

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

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

    3 回复  |  直到 7 年前
        1
  •  4
  •   Programmer    7 年前

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

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

    将其添加到您的 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);
            }
        }
    }
    

    现在,您可以在 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");
    }
    

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

    不,你可以使用 EventTrigger 类来注册以下事件,您无需将其附加到每个对象:

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

    求求你了 使用它。它很慢,我也从多个人那里验证了这一点。

        2
  •  3
  •   mayo    7 年前

    以统一为中心的解决方案是使用 UnityEvent 这允许您在检查器中进行这些更改。

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

    然后 LanguageDropdown 挑选出来的 成员在检查器中可见,然后可以将对象和方法目标分配给该成员(很像按钮)。

    Component with *Selected()* member visible

    注意:您可以更改 单位事件 UnityEvent<LanguageDropdown> 如果要包括源对象:

    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 void method(LanguageDropdown dropdown) )

        3
  •  1
  •   Sergiy Klimkov    7 年前

    您可以在另一个脚本中定义公共方法,并将其称为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);
        }
    }