如何在Unity3D中使用c#事件

本文关键字:事件 Unity3D | 更新日期: 2023-09-27 18:02:54

我已经在Winforms中使用Events一段时间了,但我对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");
}

我的Debug输出如下:

  1. "清醒"
  2. "昂秀"
  3. "OnShowFiring"

但是"OnShowCalled"永远不会被执行,在Unity的控制台中没有异常。我测试了EventArgs.Empty而不是评论中提到的new EventArgs(),对我的问题没有影响。

期待您的帮助

如何在Unity3D中使用c#事件

首先查看本教程: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);
    }
}

为了调试的目的,为您的组件添加一个Tag属性。然后用:

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

并更改日志

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

,你会看到你是否在处理相同的对象

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

Unity中的简单事件系统

Unity中的事件应该使用UnityEvent。

标准c#事件不像预期的那样工作,因为Unity以不同于香草c#的方式执行代码(我不太了解这个主题,但我相信其他人知道)。

此外,Unity使用实体组件系统。详细信息请参见http://answers.unity3d.com/questions/669643/entity-component-system.html