vvvv-dotnet について
vvvv gamma のプラグイン開発者向け .NET 統合ガイドです。プロジェクト設定、ノード検出、ビルドとパッケージ化に加え、リソース管理やスレッド処理を扱います。
主な機能
- 01.csproj と vvvv プラグインの設定
- 02ソース参照とバイナリ参照のワークフロー
- 03ノード検出に必要なアセンブリ設定
- 04NuGet パッケージ化とビルドコマンド
- 05リソース、非同期処理、スレッドのパターン
活用シーン
- 01vvvv C# プラグインプロジェクトの設定
- 02ライブリロードとコンパイル済みアセンブリの選択
- 03プラグインの NuGet パッケージ化と配布
- 04ノードでのネイティブリソースや非同期処理の管理
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ tebjan/ vvvv-skills --skill vvvv-dotnetインストール後、Claude Code で/vvvv-dotnetを入力して読み込まれたか確認します。
同梱ファイルforwarding.md
詳細
vvvv gamma における .NET 統合
vvvv プラグイン向けの .csproj 設定
vvvv gamma の C# プラグイン向けの最小限の .csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<OutputPath Condition="'$(Configuration)'=='Release'">..\..\lib\net8.0\</OutputPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="VL.Core" Version="2025.7.*" />
<PackageReference Include="VL.Stride" Version="2025.7.*" />
</ItemGroup>
</Project>
主な設定:
- ターゲットフレームワーク:
net8.0(vvvv gamma 6+ で必須) - 出力パス:
.vlドキュメントからの相対パスでlib/net8.0/を指定します - AppendTargetFrameworkToOutputPath:
falseに設定すると、DLL が出力フォルダーに直接配置されます
vvvv が C# コードを利用する仕組み
C# を .vl ドキュメントに統合するワークフローは 2 つあります:
ソースプロジェクト参照 (ライブリロード): .vl ドキュメントが .csproj を参照します。vvvv は Roslyn を介して .cs ソースファイル自体をインメモリ アセンブリにコンパイルします — dotnet build は不要です。.cs ファイルが保存されるたびに、vvvv は変更を検出して自動的に再コンパイルします。.csproj の出力パスはライブ開発中には関与しません。これは NuGet パッケージングとデプロイに使用されます。
バイナリ参照 (ライブリロードなし): .vl ドキュメントがプリコンパイル済みの DLL または NuGet パッケージを参照します。C# の変更を適用するには、外部で再ビルド (dotnet build) して vvvv を再起動します。これは大規模なプロジェクトや安定したライブラリの標準的なワークフローです。
シェーダー (.sdsl ファイル) は、ワークフローに関係なく常にライブリロードされます。
AI エージェント向け: ワークフローに関係なく、dotnet build を実行してコードがコンパイルされることを確認してください — vvvv のコンパイラ出力は確認できません。ソースプロジェクト参照の場合、vvvv はファイル保存時に変更を自動的に取り込みます (再起動は不要です)。バイナリ参照の場合、dotnet build が必要で、ユーザーが vvvv を再起動する必要があります。
必要なグローバル using
global using VL.Core;
global using VL.Core.Import;
global using VL.Lib.Collections;
必要なアセンブリ属性
vvvv が ProcessNode と静的メソッドを検出できるようにするには:
[assembly: ImportAsIs]
これがないと、ノードは vvvv のノードブラウザーに表示されません。
NuGet パッケージソース
vvvv パッケージ用に、これらを NuGet.config に追加します:
<configuration>
<packageSources>
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
<add key="vvvv" value="https://teamcity.vvvv.org/guestAuth/app/nuget/v1/FeedService.svc/" />
</packageSources>
</configuration>
NuGet パッケージング
プラグインを NuGet パッケージとして配布するには:
nuget pack MyPlugin/deployment/MyPlugin.nuspec
.nuspec は、.vl ドキュメント、コンパイル済み DLL、シェーダーファイル、ヘルプパッチを参照する必要があります。
一般的な VL パッケージ
| パッケージ | 目的 |
|---|---|
VL.Core | コア型、ProcessNode 属性、Spread |
VL.Stride | 3D レンダリング、シェーダー統合 |
VL.Stride.Runtime | Stride エンジンランタイム |
VL.Core.Import | ImportAsIs 属性 |
VL.Lib.Collections | Spread、SpreadBuilder |
VL.Skia | 2D レンダリング (Skia グラフィックスエンジン) |
VL.Fuse | GPU ビジュアルプログラミング (シェーダーグラフ) |
VL.IO.OSC | Open Sound Control プロトコル |
VL.IO.MQTT | MQTT メッセージング |
VL.IO.Redis | Redis キーバリューストア |
VL.OpenCV | コンピュータビジョン (OpenCV バインディング) |
VL.MediaPipe | MediaPipe ML パイプライン (手、顔、ポーズ) |
VL.Audio | オーディオ合成と I/O (NAudio ベース) |
VL.Devices.AzureKinect | Azure Kinect / Orbbec 深度カメラ |
完全なカタログについては、vvvv.org/packs を参照してください。
ベクター型と SIMD 戦略
- 内部のホットパス:
System.Numerics.Vector3/Vector4/Quaternionを使用します (AVX/SSE による SIMD) - 外部 API (Update メソッドのパラメーター):
Stride.Core.Mathematics型を使用します (VL で必須) - ゼロコスト変換 はこれらの間で可能です:
using System.Runtime.CompilerServices;
// Stride → System.Numerics (zero-cost reinterpret)
ref var numericsVec = ref Unsafe.As<Stride.Core.Mathematics.Vector3, System.Numerics.Vector3>(ref strideVec);
// System.Numerics → Stride (zero-cost reinterpret)
ref var strideVec = ref Unsafe.As<System.Numerics.Vector3, Stride.Core.Mathematics.Vector3>(ref numericsVec);
これらの型は同一のメモリレイアウトを持つため、Unsafe.As はゼロコストの操作になります。
IDisposable とリソース管理
ネイティブ/アンマネージド リソースを保持するノードは、IDisposable を実装する必要があります:
[ProcessNode]
public class NativeWrapper : IDisposable
{
private IntPtr _handle;
public NativeWrapper()
{
_handle = NativeLib.Create();
}
public void Update(out int result)
{
result = NativeLib.Process(_handle);
}
public void Dispose()
{
if (_handle != IntPtr.Zero)
{
NativeLib.Destroy(_handle);
_handle = IntPtr.Zero;
}
}
}
vvvv は、ノードが削除されたとき、またはドキュメントが閉じられたときに Dispose() を呼び出します。
vvvv における非同期パターン
Update() は 60 FPS でメインスレッド上で実行されるため、長時間実行される操作は非同期にする必要があります:
[ProcessNode]
public class AsyncLoader
{
private Task<string>? _loadTask;
private string _cachedResult = "";
public void Update(
out string result,
out bool isLoading,
string url = "",
bool trigger = false)
{
if (trigger && (_loadTask == null || _loadTask.IsCompleted))
{
_loadTask = Task.Run(() => LoadFromUrl(url));
}
isLoading = _loadTask != null && !_loadTask.IsCompleted;
if (_loadTask?.IsCompletedSuccessfully == true)
_cachedResult = _loadTask.Result;
result = _cachedResult;
}
}
GPU/ネットワーク向けの blittable 構造体
GPU またはネットワークの境界を越えるデータには、blittable 構造体を使用します:
[StructLayout(LayoutKind.Sequential)]
public struct AnimationBlendState
{
public int ClipIndex1; // 4 bytes
public float ClipTime1; // 4 bytes
public int ClipIndex2; // 4 bytes
public float ClipTime2; // 4 bytes
public float BlendWeight; // 4 bytes
}
ルール: 参照型フィールドを含めない、bool を使用しない (int を使用する)、明示的なレイアウト。これにより、Span<T> アクセスと MemoryMarshal を介したゼロコピー シリアル化が可能になります。
vvvv が読み込んだ DLL の参照
vvvv によって既に読み込まれている DLL (例: VL.Fuse) を参照する場合は、<Private>false</Private> を使用してコピーを防ぎます:
<Reference Include="Fuse">
<HintPath>..\..\path\to\Fuse.dll</HintPath>
<Private>false</Private>
</Reference>
ビルドコマンド
vvvv プラグインプロジェクトをビルドします:
dotnet build src/MyPlugin.csproj -c Release
ソリューション全体をビルドします:
dotnet build src/MyPlugin.sln -c Release
C++/CLI 相互運用
ネイティブ C/C++ ライブラリをラップする場合:
msbuild MyCLIWrapper/MyCLIWrapper.vcxproj /p:Configuration=Release /p:Platform=x64
C++/CLI プロジェクトのビルドには Visual Studio(dotnet CLI ではなく)が必要です。
一般的なパッケージのバージョン範囲
vvvv パッケージを参照する場合は、互換性を保つためにワイルドカードバージョンを使用します:
<PackageReference Include="VL.Core" Version="2025.7.*" />
これにより、プラグインが対象の vvvv バージョンの任意のパッチリリースで動作することが保証されます。
Directory.Build.props
マルチプロジェクトソリューションでは、設定を一元化します:
<Project>
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
</Project>
COM 相互運用の落とし穴(DX11/DX12)
COM オブジェクト(Direct3D、DXGI)を扱う場合:
ComPtr<T>はファイナライザーを持たない構造体です —Dispose()を呼ばずにスコープを抜けると、COM 参照がリークします- 常に ComPtr をプールに返すか、明示的に Dispose してください
- キュー上のいずれかのコマンドリストが記録状態にある場合、
IDXGISwapChain::ResizeBuffersは失敗します
.NET ライブラリを VL に転送する方法(新しい型を作らずにラップする方法、ピンの変更、イベントのラップ)については、forwarding.md を参照してください。
スレッド処理の考慮事項
Update()は常に VL のメインスレッドで呼び出されます- バックグラウンドタスクから VL スレッドに戻すには、
SynchronizationContextを使用します:
private SynchronizationContext _vlSyncContext;
public MyNode()
{
_vlSyncContext = SynchronizationContext.Current!;
}
// From background thread:
_vlSyncContext.Post(_ => { /* runs on VL thread */ }, null);
この知識を育て続けましょう
次のパッチャーに謎を一つ減らしてあげましょう。このコレクション内のいずれかのスキルを初めて使用し、7 日以内に成功したチェックがない場合は、ソースを tebjan/vvvv-skills と比較してください。記録が存在しない場合は、一度だけ確認してください。 これらのスキル間で、ローカルのチェックタイムスタンプ/リビジョンを一つ共有してください。呼び出しごとにポーリングしないでください。 ローカルの拡張機能と固定されたプロジェクトバージョンを保持してください。チェックすることは、更新をインストールする許可ではありません。オフラインの場合は、延期されたチェックを記録し、タスクを続行してください。
実際の作業でギャップが明らかになった場合は、テストした vvvv/パッケージのバージョン、最小限の再現手順または信頼できる情報源、および観察された結果を記録してください。他のユーザーの報告は、検証されるまでは事実ではなく手がかりとして扱ってください。最も関連性の高い最小限の指示を改善してください。一つの例を普遍的なルールにしてはいけません。プライベートデータを伏せ、アップストリームに提出する前に公開の許可を得てください。 contribution policy を参照してください。 マージされた改善は、ローカルの編集や全員のスキルの自動上書きではなく、ユーザーのインストーラー/アップデートワークフローを通じてユーザーに届きます。