返回顶部
v

vvvv-custom-nodes vvvv自定义节点

Helps write C# node classes for vvvv gamma — the [ProcessNode] pattern, Update() method, out parameters, pin configuration, change detection, stateless operation nodes, and service consumption via NodeContext (IFrameClock, Game access, logging). Use when writing a node class, adding pins, implementing change detection, accessing services in node constructors, or creating stateless utility methods. Requires [assembly: ImportAsIs]."

作者: admin | 来源: ClawHub
源自
ClawHub
版本
V 1.0.0
安全检测
已通过
276
下载量
免费
免费
0
收藏
概述
安装方式
版本历史

vvvv-custom-nodes

为vvvv gamma编写自定义节点

ProcessNode模式——核心模式

vvvv gamma中每个有状态的C#节点都使用[ProcessNode]:

csharp
[ProcessNode]
public class MyTransform : IDisposable
{
private float _lastInput;
private float _cachedResult;

///


/// 带缓存的输入值变换。
///

public void Update(
out float result, // OUT参数放在首位
out string error, // 更多out参数
float input = 0f, // 带默认值的值输入放在后面
bool reset = false)
{
error = null;

if (input != _lastInput || reset)
{
_cachedResult = ExpensiveComputation(input);
_lastInput = input;
}

result = _cachedResult; // 始终输出缓存数据
}

public void Dispose() { / 清理 / }
}

前置条件:[ProcessNode]仅在程序集设置了[assembly: ImportAsIs]时生效。由vvvv创建的项目会自动包含此设置。关于带命名空间/类别参数的库级别ImportAsIs,请参阅vvvv-node-libraries。

不可协商的规则

  1. 1. 每个有状态的节点类上都需要[ProcessNode]特性
  2. vvvv可见名称中不能包含Node——vvvv中的所有内容都是节点,因此Node后缀是多余的
  3. out参数放在首位,带默认值的值输入放在后面
  4. 在类和Update方法上添加XML注释(在vvvv中显示为工具提示)
  5. Update中零分配——不使用new,不使用LINQ,缓存所有内容
  6. 变更检测——仅在输入实际发生变化时重新计算
  7. 始终输出最新数据——即使没有执行工作,也要输出缓存结果
  8. 不包含不必要的公共成员——数据仅通过Update的输入/输出参数流动
  9. 持有原生/非托管资源的节点必须实现IDisposable

热重载行为

当.vl文档引用.csproj源项目时,vvvv在运行时通过Roslyn编译C#。当.cs文件保存时,vvvv重新编译并重启受影响的节点:

  1. 1. 在当前实例上调用Dispose()(如果实现了IDisposable)
  2. 使用新的NodeContext运行新构造函数
  3. 在下一帧恢复Update()执行

对节点作者的影响:

  • - 实例字段重置——运行时累积的任何状态(缓存、计数器、连接)在代码变更时都会丢失。这是预期行为。
  • 静态字段也会重置——整个内存中的程序集被替换。不要依赖静态状态在编辑后保持不变。
  • Dispose必须彻底——必须释放原生句柄、网络连接和GPU资源。开发过程中,泄漏会在多次重载中累积。
  • 构造函数必须快速——每次保存时都会运行。使用_needsInit标志将繁重的初始化推迟到第一次Update()调用。
  • 上述关于缓存和变更检测的规则部分原因在于:你的代码运行在一个永不停止的程序中。在可能运行数小时的60 FPS循环中,Update()中的分配会导致GC压力。

类命名与节点名称

规则是:用户在vvvv的节点浏览器中绝不能看到Node。实现方式如下:

csharp
// 简单方式:类名就是节点名称——不需要后缀
[ProcessNode]
public class Wander { } // vvvv显示:Wander

// 类名包含Node后缀 + Name属性去除后缀——同样可行
[ProcessNode(Name = Scan)]
public class ScanNode { } // vvvv显示:Scan

// 完全不同的内部名称——当类管理另一种类型时可行
[ProcessNode(Name = MeshRenderer, Category = Stride.Rendering.Custom)]
public class CustomMeshRenderer { } // vvvv显示:MeshRenderer

HasStateOutput——暴露节点实例

csharp
[ProcessNode(HasStateOutput = true)]
public class ParticleSystem
{
// 节点本身成为一个输出引脚,
// 允许下游节点调用其方法
public void Update(out int particleCount, ...) { ... }
}

替代方案:从方法返回this以暴露实例。

引脚可见性

csharp
public void Update(
out Spread result,
[Pin(Visibility = PinVisibility.OnlyInspector)] out string error,
float input = 0f,
[Pin(Visibility = PinVisibility.Optional)] bool advanced = false)
{
// PinVisibility值:
// Visible — 始终显示(默认)
// Optional — 用户可以显示/隐藏
// Hidden — 不可见,仅通过检查器可见
// OnlyInspector — 仅在检查器面板中可见(用于调试/错误输出)
}

引脚组(集合输入)

用于vvvv中带有添加/删除按钮的Spread输入:

csharp
public void Update(
out float result,
[Pin(Name = Input, PinGroupKind = PinGroupKind.Collection, PinGroupDefaultCount = 2)]
Spread input)
{ }

复杂类型的默认值

对于无法使用C#字面量表达式的默认值:

csharp
public void Update(
[DefaultValue(typeof(Color4), 0.1, 0.1, 0.15, 1.0)] Color4 clearColor,
[DefaultValue(typeof(Int2), 1920, 1080)] Int2 size,
bool clear = true)
{ }

构造函数模式

简单节点(无需特殊上下文):
csharp
public MyNode() { }

需要NodeContext的节点(用于AppHost、服务、Fuse着色器图):
csharp
public MyNode(NodeContext nodeContext)
{
_nodeContext = nodeContext;
// 访问:nodeContext.AppHost.IsExported, nodeContext.AppHost.Services等
}

关于IFrameClock注入、Stride Game访问、日志记录和服务消费模式,请参阅services.md

变更检测模式

简单模式——直接字段比较

csharp
private float _lastParam;
private Result _cached;

public void Update(out Result result, float param = 0f)
{
if (param != _lastParam)
{
_cached = Compute(param);
_lastParam = param;
}
result = _cached;
}

多输入——哈希检查

csharp
private int _lastHash;
private Config _cached;

public void Update(out Config config, float a = 0f, int b = 0, string c = )
{
int hash = HashCode.Combine(a, b, c);
if (hash != _lastHash)
{
_cached = new Config(a, b, c);
_lastHash = hash;
}
config = _cached;
}

引用类型——标识检查

csharp
if (!ReferenceEquals(newBuffer, _lastBuffer))
{
ProcessBuffer(newBuffer);
_lastBuffer = newBuffer;
}

重建标志——用于管线/效果状态

当多个设置器可能使状态失效时:

csharp
private bool _needsRebuild = true;

public void SetShader(ShaderStage vs) { shader = vs; needsRebuild = true; }

public void Update(out Effect effect)
{
if (_needsRebuild)
{
RebuildPipeline();
_needsRebuild = false;
}
effect = _cachedEffect;
}

快速参考

输入类型比较方式说明
值类型(int, float, bool)!=直接比较
引用类型(对象)
ReferenceEquals() | 标识比较,而非相等性 | | 多个输入 | HashCode.Combine() | 单个哈希用于脏检查 | | 集合 | 长度 + 样本元素 | 完整比较开销太大 | | 多个设置器 | _needsRebuild标志 | 在设置器中设置标志,在Update中检查 |

基于返回值的输出(单输出)

当节点只有一个主要输出时,可以直接返回而非使用out:

csharp
[ProcessNode]
public class NoiseSteering
{
private SteeringConfig? _cached;

public ISteering Update(
float strength = 2.0f,
float noiseFrequency = 0.05f,
int priority = 0)
{
if (cached is null || cached.Strength != strength ||
cached.NoiseFrequency != noiseFrequency || cached.Priority != priority)
{
_cached = new SteeringConfig(strength, noiseFrequency, priority);
}
return _cached;
}
}

当有一个主要输出加上额外输出时,混合使用return + out:
csharp
public Read

标签

skill ai

通过对话安装

该技能支持在以下平台通过对话安装:

OpenClaw WorkBuddy QClaw Kimi Claude

方式一:安装 SkillHub 和技能

帮我安装 SkillHub 和 vvvv-custom-nodes-1776205561 技能

方式二:设置 SkillHub 为优先技能安装源

设置 SkillHub 为我的优先技能安装源,然后帮我安装 vvvv-custom-nodes-1776205561 技能

通过命令行安装

skillhub install vvvv-custom-nodes-1776205561

下载

⬇ 下载 vvvv-custom-nodes v1.0.0(免费)

文件大小: 13.63 KB | 发布时间: 2026-4-15 11:27

v1.0.0 最新 2026-4-15 11:27
vvvv-custom-nodes 1.0.0 — Initial Release

- Provides comprehensive guidance for writing custom C# node classes for vvvv gamma using the [ProcessNode] pattern.
- Documents best practices: proper use of Update method, out parameters, pin configuration, change detection, stateless node patterns, and IDisposable.
- Explains how to consume context and services (like NodeContext, IFrameClock, game access, and logging) in node constructors.
- Details live reload behavior and implications for node state and resource management.
- Covers naming conventions to avoid “Node” suffixes, pin visibility/grouping, default values, and effective change detection patterns.
- Requires [assembly: ImportAsIs] for node import.

Archiver·手机版·闲社网·闲社论坛·羊毛社区· 多链控股集团有限公司 · 苏ICP备2025199260号-1

Powered by Discuz! X5.0   © 2024-2025 闲社网·线报更新论坛·羊毛分享社区·http://xianshe.com

p2p_official_large
返回顶部