NodeScript 系统总览
文件结构
一、执行模型:拉取式 + 生命周期
1.1 周期调度
1.2 节点状态
| 状态 |
含义 |
Ready |
等待本周期执行 |
Hang |
前置节点未完成,挂起到下一周期 |
Complete |
已完成,移出 runtimeTable |
1.3 LoopResult 返回类型
| 工厂方法 |
RemoveFromRuntime |
TriggerDownstream |
用途 |
Complete() |
true |
true |
节点完成,触发下游 |
Hang(preceding) |
false |
false |
等待前置节点 |
Repeat() |
false |
true |
保持活跃+触发下游(循环迭代) |
Wait() |
false |
false |
空转一周期(循环等下游消费) |
1.4 L 值
- BFS 从
NodeStart/NodeEntry 开始计算,L 值显示在节点标题栏 (L:N)
- 仅显示,不约束连线
- L=-1 表示孤立节点(无路径可达)
1.5 防自循环
连线 A→B 时,从 B 出发沿现有边 DFS,看能否回到 A。能回到则拒绝连线。
二、类型系统
2.1 连接器体系
2.2 InputAny / OutputAny
| 特性 |
说明 |
| 初始状态 |
DataType = null,连接点显示灰色 |
| 连线锁定 |
连线后自动 LockType(T),连接点变为类型对应颜色 |
| 类型传播 |
锁定后 OnTypePropagated(T) → 同节点其他未锁定端口跟随 |
IsFixedType |
true 时阻止传播覆盖,如 NodeLerp.t 固定为 float |
| 可改类型 |
LockType 允许覆盖(防止 NodeConst 切换类型后 DataType 不更新) |
2.3 Input 拉取模型
Value 优先读 Output<T>._value,回退读 OutputAny
ConnectAny(IOutput) 支持 OutputAny → Input<T> 桥接(如 NodeConst → NodeMath.a)
GetSourceNode() 兼容两种源
2.4 Output 反向写入
_writeBack 回调:NodeSet 通过 targetRef 修改 NodeVariable 的内部值
2.5 类型兼容表
| from |
to |
兼容 |
| null |
* |
✓(未锁定端口) |
| T |
T |
✓ |
| int |
float |
✓ |
| float |
int |
✓ |
| 其他 |
其他 |
✗ |
2.6 类型颜色
| 类型 |
颜色 |
| float |
蓝 |
| int |
青 |
| bool |
橙 |
| string |
紫 |
| Vector2 |
黄 |
| Vector3 |
绿 |
| Color |
粉 |
| GameElement |
深紫 |
| Signal |
白 |
| List<GameElement> |
暗紫 |
| null(未锁定) |
灰 |
三、节点目录
3.1 入口节点
| 节点 |
输入 |
输出 |
说明 |
NodeStart |
— |
exec(Signal), element(GameElement) |
图入口,绑定当前选中元素 |
NodeEntry |
— |
exec(Signal) |
纯信号入口 |
3.2 运算节点
| 节点 |
输入 |
输出 |
说明 |
NodeMath |
a(Any), b(Any, fixed) |
result(Any) |
+-*/ 四则,支持 float/int/V2/V3/Color/string |
NodeLerp |
a(Any), b(Any), t(float,fixed) |
result(Any) |
线性插值,t 未连默认 0.5 |
NodeCompare |
a(Any), b(Any) |
result(bool) |
== != > < >= <= |
3.3 向量节点
| 节点 |
输入 |
输出 |
说明 |
NodeSplit |
input(Any) |
x/y/z/w(float) |
V2 输出 xy,V3 输出 xyz,Color 输出 rgba |
NodeCombine |
x/y/z/w(float) |
output(Any) |
UI 选类型后合并为 V2/V3/Color |
NodeGetTransform |
element(GE) |
pos/rot/scl(V3) |
读取元素变换 |
NodeSetTransform |
exec(Sig), element(GE), Pos/Rot/Scl(V3) |
— |
设置元素变换 |
3.4 数据节点
| 节点 |
输入 |
输出 |
说明 |
NodeConst |
— |
value(Any) |
UI 选类型+填值,6 种类型统一 |
NodeVariable<T> |
signal(Sig), set(T) |
get(T) |
变量存储;signal 连着时等触发才更新 |
NodeSet |
targetRef(Any), value(Any) |
— |
反向写入 targetRef 指向的变量 |
NodeSelect |
cond(Any), true(Any), false(Any) |
result(Any) |
二选一,cond 未连用 UI Toggle |
3.5 控制流节点
| 节点 |
输入 |
输出 |
说明 |
NodeBranch |
exec(Sig), cond(Any) |
true/false(Sig) |
cond>0 走 true,否则 false |
NodeForLoop |
exec(Sig), count(Any) |
loopBody(Sig), index(int), completed(Sig) |
多周期交替:输出→Wait→输出→Wait... |
3.6 集合节点
| 节点 |
输入 |
输出 |
说明 |
NodeList<T> |
— |
output(List<T>) |
空列表 |
NodeListAdd<T> |
list(List<T>), item(T) |
output(List<T>) |
追加元素 |
NodeListGet<T> |
list(List<T>), idx(UI) |
element(T) |
索引取值 |
NodeForEach |
exec(Sig), list(Any) |
loopBody(Sig), current(Any), index(int), completed(Sig) |
非泛型,连 List<X> 自动锁定 current 为 X |
3.7 GameElement 操作
| 节点 |
输入 |
输出 |
说明 |
NodeGameElement |
exec(Sig), Root(GE), Source(GE) |
newElement(GE), completed(Sig) |
复制粘贴元素 |
NodeChildByIndex |
parent(GE), idx(UI) |
child(GE) |
子元素按索引 |
NodeChildCount |
parent(GE) |
count(int) |
子元素个数 |
NodeClone |
exec(Sig), source(GE) |
clone(GE) |
Instantiate 克隆 |
3.8 调试节点
| 节点 |
输入 |
输出 |
说明 |
NodeDebugLog |
exec(Sig), value(Any) |
— |
带 Signal 等待的日志 |
NodeLog |
value(Any) |
— |
直接打印日志 |
四、所有节点统一规范
每个节点的 Loop() 遵循:
EnsureInputsReady() 在 NodeBase 上定义,自动检查 GetPrecedingNodes() 中所有上游的 Status。
五、UI 特性
5.1 节点外观
- 半透明背景 + 标题栏
Name (L:N)
statusImage:Ready 灰 / Hang 橙黄 / Complete 绿
- 选中节点蓝色高亮
5.2 连接线
UILineRenderer 贝塞尔曲线
- 手动距离检测悬停(不依赖 Unity 射线)
- 悬停加粗 +3px,选中加粗 ×2
- RectTransform 自动缩放到包围盒
- 拖线时 dragLine 不参与射线
5.3 交互
| 操作 |
功能 |
| 左键空白 |
取消所有选中 |
| 左键节点 |
选中节点(Shift 多选) |
| 左键拖节点 |
移动节点 |
| 左键拖输出点→输入点 |
连线 |
| 左键线 |
选中线(Shift 多选) |
| 中键拖面板 |
平移整个画布 |
| Ctrl+右键 |
右键菜单创建节点 |
| Delete |
删除选中 |
5.4 快捷键
| 快捷键 |
功能 |
F3 |
新建/销毁 NodeScript 编辑器 |
Enter |
完整运行图 |
Shift+Enter |
单步调试(首次初始化) |
Esc |
退出调试模式 |
Ctrl+Enter |
运行图(保留) |
F5 |
拓扑预览(打印分层执行计划) |
F1 |
保存 |
F2 |
加载 |
Ctrl+C/V |
复制/粘贴节点 |
Delete |
删除选中 |
5.5 控制台命令
| 命令 |
说明 |
newNode |
新建/销毁 NodeScript 编辑器 |
saveNode |
保存到默认 graph.json |
saveNode name |
另存为 {name}.json |
loadNode name |
从 {name}.json 加载 |
六、调试功能
6.1 单步调试 (Shift+Enter)
每步打印详细日志:
statusImage 同步变色。
6.2 拓扑预览 (F5)
七、NodeManager 关键 API
| 方法 |
说明 |
Init(GameElement) |
绑定元素 + 创建 Start 节点 |
RunGraph() |
完整执行(生命周期循环) |
ComputeLValues() |
重算所有节点的 L 值 + 刷新标题 |
SaveToFile(string?) |
保存图,null 用默认路径 |
LoadFromFile(string?) |
加载图 |
GetSavePath(string) |
获取完整保存路径 |
八、文件存储
| 项目 |
路径 |
| 保存目录 |
Assets/StreamingAssets/NodeScript/ |
| 默认文件 |
graph.json |
| 自定义文件 |
{name}.json |
九、待完成 (Phase 4+)