可编写脚本的对象事件无法在 Unity 中注册侦听器(记录类型不匹配)

问题描述 投票:0回答:1

我正在尝试遵循在 Youtube 上找到的使用可编写脚本的对象处理事件的教程,该教程位于此处:https://www.youtube.com/watch?v=7_dyDmF0Ktw

因此,我得到了两个脚本,据我所知,它们与他正在使用的脚本相匹配,如下所示: 脚本1:

[CreateAssetMenu(menuName = "GameEvent")]
public class GameEvent : ScriptableObject
{
    private List<GameEventListener> listeners = new List<GameEventListener>();

    public void Raise()
    {
        Raise(null, null);
    }
    
    public void Raise(Component sender, object data)
    {
        for (int i = 0; i < listeners.Count; i++)
        {
            listeners[i].OnEventRaised(sender, data);
        }
    }

    public void RegisterListener(GameEventListener listener)
    {
        Debug.Log(listener.GetType());
        if (!listeners.Contains(listener))
        {
            listeners.Add(listener);
        }
        Debug.Log(listeners[0]);
    }

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

脚本2:

[Serializable] public class CustomUnityEvent : UnityEvent<Component, object> { }

public class GameEventListener : MonoBehaviour
{
    public GameEvent gameEvent;
        
    public CustomUnityEvent response;

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

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

    public void OnEventRaised(Component sender, object data)
    {
        response.Invoke(sender, data);
    }
}

我已将脚本添加到适当的对象,并按照视频中的方式创建事件,并设置所有必需的引用。问题出现在 RegisterListener 方法期间。正如您在脚本 1 中看到的,我包含了 2 个调试打印输出。在第一个中,它获取侦听器的类型,这正确地显示为“GameEventListener”,但是在注册步骤之后,第二个调试记录已添加到列表中的内容是空引用。

预期的结果是添加一个 GameEventListener。我使用的是Unity 2021.3.25。 我的代码中是否缺少某个步骤?当类型在此之前报告为 GameEventListener 时,为什么要添加 null?

我尝试将列表设置为公开和私有,我认为这不会产生影响,结果是相同的。我仍然期望它添加一个 GameEventListener,因为这是调试中显示的类型,但它添加了一个 null,这导致列表中的类型不匹配。

list unity-game-engine events null scriptable-object
1个回答
0
投票

这没有任何意义。如果集合不包含项目,您将其删除吗?

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

Remove 如果成功则返回 true,如果失败则返回 false。所以你可以检查一下你是否真的想确保某些东西被删除了

public void UnregisterListener(GameEventListener listener)
{
    if (listeners.Remove(listener))
    {
        //On listener removed can be added here later
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.