Unity 中的简单事件系统

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

我正在尝试在 Unity 中使用事件系统(C# 方式),但在实现它时遇到问题。

大多数示例都显示一个类,您可以在其中定义处理程序;然后你在同一个类中编写与处理程序的签名匹配的函数,并将事件编写为静态

public class EventExample : MonoBehaviour
{
    public delegate void ExampleEventHandler();
    public static event ExampleEventHandler OneDayPassed;

    public static void NextTurn()
    {
        // do stuff then send event
        if (OneDayPassed != null)
            OneDayPassed();
    }
}

然后在另一个类中,您订阅事件,创建一个实际执行某些操作的函数

public class EntityWatcher: MonoBehaviour
{
    void Start()
    {
        EventExample.OneDayPassed += this.PrepareNextDay;
    }

    public void PrepareNextDay()
    {
        // Do other stuff that happen after the day is done

    }
}

到目前为止没有问题,但我不确定如何设计这个,所以任何特定类型的游戏对象都会订阅这个事件。例如,如果您有一个 GO 员工类别,即工作 8 到 6 个,并且您在运行时实例化它们;我应该订阅该类别的主类,还是应该创建一个附加到游戏对象预制件的脚本来订阅该事件?

目标是让所有应该在体育中心进行 8 到 6 班倒的工作人员知道“一天结束”事件何时启动,但我不想订阅我实例化的每一个预制件。

根据我的理解,我应该在预制件上附加一个包含所需代码的脚本,但我找不到一个实际的示例来说明这是否确实是这样做的方法。

c# events unity-game-engine
3个回答
43
投票

您必须使用

UnityEvent

public UnityEvent whoa;

这非常简单。

制作脚本 BigScript.cs

using UnityEngine;
using System.Collections;
using UnityEngine.Events;

public class BigScript:MonoBehaviour
{
    [Header("Here's a cool event! Drag anything here!")]
    public UnityEvent whoa;
}

将其放在游戏对象上。 现在在检查器中查看它

您将看到“哇”事件。

只需将您的other脚本拖到那里,当“哇”发生时,在那些other脚本上发生一些事情。

enter image description here

就这么简单。要在 BigScript 中调用事件,只需

    [Header("Here's a cool event! Drag anything here!")]
    public UnityEvent whoa;
    
    private void YourFunction()
    {
        whoa.Invoke();
    }

在极少数情况下,您可能需要通过代码添加侦听器,而不是简单地将其拖动到编辑器中。这是微不足道的:

whoa.AddListener(ScreenMaybeChanged);
(通常情况下

您不必这样做。只需拖动即可连接。我只是为了完整起见才提到这一点。)


仅此而已。

请注意互联网上有关此主题的过时示例代码。


上面展示了如何连接没有参数的简单函数

如果你确实需要争论:

这是一个函数具有 ONE FLOAT 参数的示例:

只需在文件顶部添加此代码即可:

[System.Serializable] public class _UnityEventFloat:UnityEvent<float> {}

然后照常进行。就这么简单。

// ... using UnityEngine.Events; // add this magic line of code up top... [System.Serializable] public class _UnityEventFloat:UnityEvent<float> {} public class SomeThingHappens : MonoBehaviour { // now proceed as usual: public _UnityEventFloat changedLength; void ProcessValues(float v) { // ... changedLength.Invoke(1.4455f); } }

当您从其他函数拖动到此函数上的编辑器插槽时:

一定要使用“动态浮动”部分。

enter image description here (令人困惑的是,你的函数

也将在“静态参数”部分中列出!这是Unity中的一个巨大问题!)


2
投票

所以:只需让每个实例订阅该事件并完成即可。


0
投票

链接:

https://assetstore.unity.com/packages/tools/utilities/gkevent-297423

© www.soinside.com 2019 - 2024. All rights reserved.