【问题标题】:How to use C# events in Unity3D如何在 Unity3D 中使用 C# 事件
【发布时间】:2016-08-18 15:03:02
【问题描述】:

我已经在 Winforms 中使用 Event 一段时间了,但我对 Unity 的东西还是很陌生。我的项目只是让一些 C# 代码在 Android 上运行,因此不需要超级高效的解决方案,只需一个有效的解决方案即可。

事件处理程序声明:

public event EventHandler OnShow, OnHide, OnClose;

事件处理程序调用:

Debug.Log("OnShow");
if (OnShow != null) 
{
Debug.Log("OnShow_Firing");
OnShow(this, new EventArgs()); 
}
else{
Debug.Log("OnShow_empty");
}

事件处理程序添加到其他脚本但相同的游戏对象中

void Awake(){
Debug.Log("Awake");
this.gameObject.GetComponent<windowScript>().OnShow += OnShowCalled;
}
private void OnShowCalled(object o,EventArgs e)
{
Debug.Log("OnShowCalled");
}

我的调试输出如下:

  1. “醒”
  2. “演出”
  3. “OnShowFiring”

但“OnShowCalled”从未执行,Unity 的控制台中没有异常。 我测试了 EventArgs.Empty 而不是 cmets 中提到的 new EventArgs() 对我的问题没有影响。

期待任何帮助。

【问题讨论】:

  • 我的猜测是另一个对象正在触发,而不是您订阅的对象。将信息添加到有助于识别对象实例的日志中,或者只是在Debug.Log("OnShow"); 上添加一个断点,然后查看它实际上是哪个对象。顺便说一句:使用EventArgs.Empty 而不是new EventArgs()
  • 场景中只有一个Gameobject同时具备这两个脚本,谢谢,我试试EventArgs.Empty
  • 你的this.gameObject.getComponent&lt;windowScript&gt;() 让我有点奇怪。您是否可能没有订阅调用OnShow() 的对象?
  • 验证 Awake() 确实被调用了
  • 只有一个游戏对象,但您正在订阅该游戏对象的脚本组件的事件。

标签: c# events unity3d


【解决方案1】:

首先查看本教程:https://unity3d.com/learn/tutorials/topics/scripting/events

我建议使用event Action。对于初学者来说更容易使用。

示例:

包含事件的类:

public class EventContainer : MonoBehaviour
{
    public event Action<string> OnShow;
    public event Action<string,float> OnHide;
    public event Action<float> OnClose;

    void Show()
    {
        Debug.Log("Time to fire OnShow event");
        if(OnShow != null)
        {
            OnShow("This string will be received by listener as arg");
        }
    }

    void Hide()
    {
        Debug.Log("Time to fire OnHide event");
        if(OnHide != null)
        {
            OnHide ("This string will be received by listener as arg", Time.time);
        }
    }



    void Close()
    {
        Debug.Log("Time to fire OnClose event");
        if(OnClose!= null)
        {
            OnClose(Time.time); // passing float value.
        }
    }
}

处理EventContainer类事件的类:

public class Listener : MonoBehaviour
{
    public EventContainer containor; // may assign from inspector


    void Awake()
    {
        containor.OnShow += Containor_OnShow;
        containor.OnHide += Containor_OnHide;
        containor.OnClose += Containor_OnClose;
    }

    void Containor_OnShow (string obj)
    {
        Debug.Log("Args from Show : " + obj);
    }

    void Containor_OnHide (string arg1, float arg2)
    {
        Debug.Log("Args from Hide : " + arg1);
        Debug.Log("Container's Hide called at " + arg2);
    }

    void Containor_OnClose (float obj)
    {
        Debug.Log("Container Closed called at : " + obj);
    }

}

【讨论】:

    【解决方案2】:

    出于调试目的,将Tag 属性添加到您的组件。然后初始化:

    var component = this.gameObject.GetComponent<windowScript>();
    component.Tag = "foo";
    component.OnShow += OnShowCalled;    
    

    并更改日志记录

    Debug.Log("OnShow: " + Tag);
    

    你会看到你是否在处理同一个对象。

    【讨论】:

      【解决方案3】:

      声誉不够,但可能重复或相关?

      Simple event system in Unity

      Unity 中的事件应该使用UnityEvent

      标准 C# 事件无法按预期工作,因为 Unity 执行代码的方式与普通 C# 不同(我对此主题了解不多,但我相信其他人会这样做)。

      此外,Unity 使用实体组件系统。请参阅http://answers.unity3d.com/questions/669643/entity-component-system.html 了解更多信息。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多