使用指南

核心概念 / 事件、执行流和数据流

解释生命周期事件、全局事件、节点事件、执行顺序和数据传递的关系。

16

Script Graph 里的逻辑不会凭空跑起来。所有工作流都要面对同一件事:什么触发了它,然后按什么顺序做,每一步用哪儿来的数据。

这三件事任何一件没想清楚,你的图就会出现”没触发/顺序错/数据为空”这三种最经典的失败之一。

搭任何图之前,先回答三个问题

问题对应能力
什么时候触发?生命周期事件、全局事件、节点事件、函数调用
触发之后按什么顺序做?执行流
每一步需要什么值?数据流

在动手之前先把这三个问题在心里过一遍。你会发现大部分图搭到一半卡住,都是因为其中某个问题没答完就动手了。

生命周期事件——组件工作流的入口

组件工作流最常用的入口是 Cocos 生命周期事件——它们和 Cocos Creator 内置的 onLoadstartupdate 一一对应:

事件什么时候触发适合做
加载组件被创建、还没进入场景交互时初始化引用、准备默认状态、打印启动标记
启动场景节点和其他组件都就绪之后开始主逻辑、绑定其他组件、发起首帧的行为
更新每一帧都会触发每帧移动、计时、输入轮询
启用面板或对象被重新启用时恢复暂停状态、重新监听
禁用被隐藏或停用时暂停计时、解绑临时监听
销毁节点被销毁前清理绑定、释放引用

选错入口是新人常见坑:想验证”能跑通”用加载启动就够了;只有需要”每帧都做”的场景(比如角色移动、CD 计时、输入轮询)才用更新。别把一次性初始化写在更新里——它会每帧都执行一次。

全局事件——跨对象通信

有些事情不是某个组件的私事,而是”整个游戏都要知道”的信号,比如:

  • GameStart — 开始游戏
  • ScoreChanged — 分数变化
  • PlayerDead — 玩家死亡
  • LevelCompleted — 关卡完成

这类事件靠全局事件系统传递。有两个建议:

  1. 把事件名放进枚举,别在多个工作流里手写字符串——枚举提供自动完成,避免一个 typo 让 UI 收不到通知。
  2. 绑定时想好解绑时机,尤其是短生命周期的对象。绑定了不解绑,对象销毁后还在收回调,就会报”访问已销毁引用”这类错。

节点事件——监听场景对象本身

按钮点击、节点碰撞、节点触摸、键盘输入……这些都是节点事件。它们的特点是”依附在具体节点上”:

  1. 找到目标节点或组件(查找节点获取组件)。
  2. 绑定对应事件(Button 点击Node 触摸键盘按下)。
  3. 在事件回调里接后续执行流。
  4. 禁用销毁时取消不再需要的绑定。

按钮、输入、碰撞类问题排查顺序几乎不变:先确认目标对不对,再确认事件是否绑定成功,最后才看回调里的逻辑。跳过前两步直接检查回调,八成会白忙一场。

执行流的顺序不是永远直线

执行线通常从事件或函数入口出发,一路往右接下去。但有几种节点会改变顺序

  • 分支 — 根据布尔值走一条路。
  • 循环 — 重复一段逻辑若干次。
  • 延迟 — 把后续推迟到未来某个时间。
  • 异步资产节点 — 加载完成后才继续。
  • 序列 — 从一个入口拆成多段依次执行。

遇到”顺序好像不对”的现象时,最快的办法是在每条关键分支后面放一个打印,让真实执行路径显式地暴露出来——不要靠猜。

数据流的来源不止一处

数据可以来自:

  • 节点自己的默认输入。
  • 变量读取节点。
  • 上游节点的输出。
  • 函数参数。
  • 事件回调里带出来的参数(比如按钮点击带出 Event)。
  • 资产选择器、节点路径选择器、组件选择器。
  • 结构体的构造或字段拆解。

如果某个节点结果不对,先打印它的输入,再打印它的输出——不要只盯着最终现象。大部分”莫名其妙的结果”都出在中间某个数据不是你以为的那个值。

继续阅读