【问题标题】:How can I send a UnityEvent to specific instance of a GameObject?如何将 UnityEvent 发送到 GameObject 的特定实例?
【发布时间】:2019-02-08 18:11:34
【问题描述】:

我有一个代表房间的预制件。我有一个在玩家进入时触发的统一事件,我有一个事件监听器,它在事件引发时改变房间的状态。它还会更改任何预制件副本的状态,而不是触发事件的房间。 如何将事件的范围缩小到仅触发事件的游戏对象的实例?

private void OnTriggerEnter2D(Collider2D other)
    {
        if (other.CompareTag("Player"))
        {
                RoomEnter.Raise();           
        }

public class GameEventListener : MonoBehaviour
    {
        [Tooltip("Event to register with.")]
        public GameEvent Event;

        [Tooltip("Response to invoke when Event is raised.")]
        public UnityEvent Response;

        private void OnEnable()
        {
            Event.RegisterListener(this);
        }

        private void OnDisable()
        {
            Event.UnregisterListener(this);
        }

        public void OnEventRaised()
        {
            Response.Invoke();
        }
    }

public class GameEvent : ScriptableObject
    {
        /// The list of listeners that this event will notify if it is raised.
        private readonly List<GameEventListener> eventListeners = 
            new List<GameEventListener>();

        public void Raise()
        {
            for(int i = eventListeners.Count -1; i >= 0; i--)
                eventListeners[i].OnEventRaised();
        }

        public void RegisterListener(GameEventListener listener)
        {
            if (!eventListeners.Contains(listener))
                eventListeners.Add(listener);
        }

        public void UnregisterListener(GameEventListener listener)
        {
            if (eventListeners.Contains(listener))
                eventListeners.Remove(listener);
        }
    }

【问题讨论】:

    标签: unity3d


    【解决方案1】:

    为什么要使用事件?当玩家进入时,调用这个房间的方法即可。

    private void OnTriggerEnter2D(Collider2D other)
    {
        if (other.CompareTag("Player"))
        {
            GetComponent<GameEventListener>().OnEventRaised();
        }
    }
    

    【讨论】:

    • 当我扩展我的代码时,我希望从不同的系统触发多个事件,并且如果可能的话,我更愿意将它们解耦。我不需要以这种方式将所有不同的系统与听众一起拉进来吗?
    • 通常事件系统是将消息从一个触发器发送到其他接收器的系统。在您的示例中,触发器和接收器是相同的,使用事件系统是多余的。如果您仍然喜欢它,没关系,但需要为 1 个房间保留 1 个 RoomEnter 实例。
    • shingo 是对的。您不能有一个通知所有人但又不通知所有人的事件。如果您坚持举办活动,则每个房间可以举办 2 场活动,一场是全球性的,另一场是独一无二的。或者你可以发送房间实例作为事件参数和一些处理程序来处理它,只有当它属于同一个房间时。
    • 您实际上可以按照 Nikaas 所说的去做。使用带有 getter 的公共字符串(例如)为您的 GameObject 创建一个组件。您可以在编辑器中初始化该字符串,并检查 other.CompareTag("Player") && other.GetComponent().YourPublicString == "SpecificObject"。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-20
    • 2023-01-17
    相关资源
    最近更新 更多