gpt4 book ai didi

c# - 运行所有 Start 方法后创建事件链

转载 作者:太空宇宙 更新时间:2023-11-03 11:59:48 25 4
gpt4 key购买 nike

我正在尝试开发一个事件驱动的游戏。起初我创建了一个带有一堆事件的单例,例如与当前关卡相关的所有事件。

public class LevelEvents : MonoBehaviour
{
public static LevelEvents instance;

public event Action onLevelRead;
public event Action onLevelSerialized;

private void Awake()
{
instance = this;
}

public void LevelRead()
{
if (onLevelRead != null)
{
onLevelRead();
}
}

public void LevelSerialized()
{
if (onLevelSerialized != null)
{
onLevelSerialized();
}
}
}

我想创建一个从读取关卡文件到序列化关卡的事件链。所以这些事件似乎非常简单。

enter image description here

我的 LevelReader 是入口点并在读取文件后调度事件。

public class LevelReader : MonoBehaviour
{
void OnEnable()
{
SceneManager.sceneLoaded += ReadLevelFile;
}

private void OnDestroy()
{
SceneManager.sceneLoaded -= ReadLevelFile;
}

private void ReadLevelFile(Scene scene, LoadSceneMode loadSceneMode)
{
// not implemented yet
LevelEvents.instance.LevelRead();
Destroy(gameObject);
}
}

序列化器将监听事件并序列化关卡。之后,它将为下一个脚本调度序列化事件

public class LevelSerializer : MonoBehaviour
{
private void Start()
{
LevelEvents.instance.onLevelRead += SerializeLevel;
}

private void OnDestroy()
{
LevelEvents.instance.onLevelRead -= SerializeLevel;
}

private void SerializeLevel()
{
// not implemented yet
LevelEvents.instance.LevelSerialized();
Destroy(gameObject);
}
}

那么问题来了。读取器在场景加载后调度读取事件。序列化程序将在启动时监听此事件。为时已晚,序列化程序将不会收到通知。我不能使用 Awake,因为这是事件单例注册 (LevelEvents) 所必需的。

想过不监听sceneLoaded事件,在Start方法中调用ReadLevelFile方法。这仍然为时已晚,因为 LevelReader 的 Start 方法被触发,Serializer 仍然不会收到通知。

如何在触发每个 Start 方法后运行 ReadLevelFile 方法?我希望得到比我的方法更好的解决方案:

  • 在 X 秒后调用此方法(计时器很危险)
  • 运行一次 Update 方法(我认为这是一个糟糕的解决方案)
  • 编写一个系统来跟踪每个 EventSubscriber 并在每个 EventSubscriber 启动其 Start 方法后触发第一个方法(这个逻辑太多了,不是吗?)
  • 定义脚本执行顺序(我认为这是一个糟糕的解决方案)

最佳答案

关于 unity docs ...

Start is called before the first frame update only if the script instance is enabled.

基于此,您可以使用协程等待下一帧开始,如下所示:

public class LevelReader : MonoBehaviour
{
// ...

void Start()
{
StartCoroutine(ReadLevelFileAfterFirstFrameCoroutine());
}

private IEnumerator ReadLevelFileAfterFirstFrameCoroutine()
{
yield return new WaitForEndOfFrame();
// Call read level file.
}

// ...
}

只需确保脚本实例实际已启用,如文档所述。
如果需要,您也可以在 Awake 中调用协程。它将在所有 AwakeStart 被调用后运行。

关于c# - 运行所有 Start 方法后创建事件链,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57543674/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com