diff --git a/Docs/VS_Scratch_Mapping.md b/Docs/VS_Scratch_Mapping.md index b4093ee..22253c0 100644 --- a/Docs/VS_Scratch_Mapping.md +++ b/Docs/VS_Scratch_Mapping.md @@ -8,7 +8,7 @@ Scratch ブロックと FUnity 独自 Visual Scripting Unit の対応関係で - `[TypeIcon(typeof(FUnityScratchUnitIcon))]` を全ユニットへ付与し、FUnity Scratch 系ユニットであることを明示する。 - ノード検索性向上のため、利用可能な場合は `[UnitSubtitle]`(または同等の検索キーワード属性)に `funity scratch` とカテゴリ名・日本語/英語の関連語を半角スペース区切りで登録する(例:`funity scratch 見た目 say speech`)。 - コード変更と同じ PR でこの対応表を更新し、タイトルやカテゴリの差異が無いよう同期する。 -- Scratch 系のコルーチン Unit は `ControlInputCoroutine` と `IEnumerator` ベースの実装を用い、スレッド登録・停止はイベント Unit 側の `ScratchUnitUtil.EnsureScratchThreadRegistered` で行う方針とする。 +- Scratch 系のコルーチン Unit は `ScratchCoroutineUnitBase.StartScratchCoroutine` を経由して実行し、開始直後に `ScratchUnitUtil.EnsureScratchThreadRegistered` でスレッド登録を行う。 ## 動き | Scratch ブロック (日本語) | FUnity Unit クラス | UnitTitle | UnitCategory | 備考 | @@ -57,11 +57,11 @@ Scratch ブロックと FUnity 独自 Visual Scripting Unit の対応関係で | Scratch ブロック (日本語) | FUnity Unit クラス | UnitTitle | UnitCategory | 備考 | | --- | --- | --- | --- | --- | | ○回繰り返す | FUnity.Runtime.Integrations.VisualScripting.Units.ScratchUnits.RepeatNUnit | ○回繰り返す | FUnity/Scratch/制御 | 指定回数ループ。定義: Runtime/.../LoopUnits.cs | -| ずっと | FUnity.Runtime.Integrations.VisualScripting.Units.ScratchUnits.ForeverUnit | ずっと | FUnity/Scratch/制御 | 永続ループ。Scratch スレッド登録で停止ブロックと連動。定義: Runtime/.../LoopUnits.cs | -| ○秒待つ | FUnity.Runtime.Integrations.VisualScripting.Units.ScratchUnits.WaitSecondsUnit | ○秒待つ | FUnity/Scratch/制御 | 指定時間待機。Scratch スレッド登録で停止ブロックと連動。定義: Runtime/.../WaitSecondsUnit.cs | +| ずっと | FUnity.Runtime.Integrations.VisualScripting.Units.ScratchUnits.ForeverUnit | ずっと | FUnity/Scratch/制御 | 永続ループ。`StartScratchCoroutine` 経由でスレッド登録し、停止ブロックと連動。定義: Runtime/.../LoopUnits.cs | +| ○秒待つ | FUnity.Runtime.Integrations.VisualScripting.Units.ScratchUnits.WaitSecondsUnit | ○秒待つ | FUnity/Scratch/制御 | 指定時間待機。`StartScratchCoroutine` 経由でスレッド登録し、停止ブロックと連動。定義: Runtime/.../WaitSecondsUnit.cs | | 自分のクローンを作る | FUnity.Runtime.Integrations.VisualScripting.Units.ScratchUnits.CreateCloneOfSelfUnit | 自分のクローンを作る | FUnity/Scratch/制御 | 自身を複製。定義: Runtime/.../CloneUnits.cs | | ○のクローンを作る | FUnity.Runtime.Integrations.VisualScripting.Units.ScratchUnits.CreateCloneOfDisplayNameUnit | ○のクローンを作る | FUnity/Scratch/制御 | 指定俳優を複製。定義: Runtime/.../CloneUnits.cs | -| クローンされたとき | FUnity.Runtime.Integrations.VisualScripting.Units.ScratchUnits.WhenIStartAsCloneUnit | クローンされたとき | Events/FUnity/Scratch/制御 | クローン生成時に発火する Scratch スクリプトの入口。`FUnityScriptThreadManager` 経由でコルーチンを開始し、直後に `ScratchUnitUtil.EnsureScratchThreadRegistered(flow, coroutine)` を呼び出す。定義: Runtime/.../CloneUnits.cs | +| クローンされたとき | FUnity.Runtime.Integrations.VisualScripting.Units.ScratchUnits.WhenIStartAsCloneUnit | クローンされたとき | Events/FUnity/Scratch/制御 | クローン生成時に発火する Scratch スクリプトの入口。イベントコルーチン開始時に `StartScratchCoroutine` でスレッド登録を行う。定義: Runtime/.../CloneUnits.cs | | このクローンを削除する | FUnity.Runtime.Integrations.VisualScripting.Units.ScratchUnits.DeleteThisCloneUnit | このクローンを削除する | FUnity/Scratch/制御 | クローンを破棄。定義: Runtime/.../CloneUnits.cs | | すべてを止める | FUnity.Runtime.Integrations.VisualScripting.Units.ScratchUnits.StopAllUnit | Scratch/すべてを止める | FUnity/Scratch/制御 | Scratch 用スレッドテーブル経由で全スレッド停止。定義: Runtime/.../StopControlUnits.cs | | このスクリプトを止める | FUnity.Runtime.Integrations.VisualScripting.Units.ScratchUnits.StopThisScriptUnit | Scratch/このスクリプトを止める | FUnity/Scratch/制御 | 現在の Scratch スレッドのみ停止。定義: Runtime/.../StopControlUnits.cs | @@ -81,11 +81,11 @@ Scratch ブロックと FUnity 独自 Visual Scripting Unit の対応関係で ## イベント | Scratch ブロック (日本語) | FUnity Unit クラス | UnitTitle | UnitCategory | 備考 | | --- | --- | --- | --- | --- | -| 緑の旗が押されたとき | FUnity.Runtime.Integrations.VisualScripting.Units.ScratchUnits.WhenGreenFlagClickedUnit | 緑の旗が押されたとき | Events/FUnity/Scratch/イベント | Runner 対象の緑の旗イベント。`FUnityScriptThreadManager` 経由でコルーチンを開始し、`ScriptMachine.nest.macro` を入口としてフローを発火する。発火時に `ScratchUnitUtil.EnsureScratchThreadRegistered(flow, coroutine)` を呼び出し、Scratch スレッドを登録する。定義: Runtime/.../GreenFlagUnits.cs | -| ○キーが押されたとき | FUnity.Runtime.Integrations.VisualScripting.Units.ScratchUnits.OnKeyPressedUnit | ○キーが押されたとき | Events/FUnity/Scratch/イベント | 押下エッジで発火する Scratch スクリプトの入口。`FUnityScriptThreadManager` 経由でコルーチンを開始し、開始直後に `ScratchUnitUtil.EnsureScratchThreadRegistered(flow, coroutine)` を呼び出す。定義: Runtime/.../InputEventUnits.cs | +| 緑の旗が押されたとき | FUnity.Runtime.Integrations.VisualScripting.Units.ScratchUnits.WhenGreenFlagClickedUnit | 緑の旗が押されたとき | Events/FUnity/Scratch/イベント | Runner 対象の緑の旗イベント。`StartScratchCoroutine` を経由してフローを発火し、開始直後に Scratch スレッドへ登録する。定義: Runtime/.../GreenFlagUnits.cs | +| ○キーが押されたとき | FUnity.Runtime.Integrations.VisualScripting.Units.ScratchUnits.OnKeyPressedUnit | ○キーが押されたとき | Events/FUnity/Scratch/イベント | 押下エッジで発火する Scratch スクリプトの入口。`StartScratchCoroutine` を経由して開始し、Scratch スレッド登録と停止ブロック連携を保証する。定義: Runtime/.../InputEventUnits.cs | | メッセージを送る | FUnity.Runtime.Integrations.VisualScripting.Units.ScratchUnits.BroadcastMessageUnit | メッセージを送る | FUnity/Scratch/イベント | 即時配信。定義: Runtime/.../MessagingUnits.cs | | メッセージを送って待つ | FUnity.Runtime.Integrations.VisualScripting.Units.ScratchUnits.BroadcastAndWaitUnit | メッセージを送って待つ | FUnity/Scratch/イベント | 同期配信後に継続。定義: Runtime/.../MessagingUnits.cs | -| メッセージを受け取ったとき | FUnity.Runtime.Integrations.VisualScripting.Units.ScratchUnits.WhenIReceiveMessageUnit | メッセージを受け取ったとき | Events/FUnity/Scratch/イベント | フィルタ一致時に発火する Scratch スクリプトの入口。`FUnityScriptThreadManager` 経由でコルーチンを開始し、開始直後に `ScratchUnitUtil.EnsureScratchThreadRegistered(flow, coroutine)` を呼び出す。定義: Runtime/.../MessagingUnits.cs | +| メッセージを受け取ったとき | FUnity.Runtime.Integrations.VisualScripting.Units.ScratchUnits.WhenIReceiveMessageUnit | メッセージを受け取ったとき | Events/FUnity/Scratch/イベント | フィルタ一致時に発火する Scratch スクリプトの入口。`StartScratchCoroutine` を経由して開始し、Scratch スレッド登録と停止ブロック連携を保証する。定義: Runtime/.../MessagingUnits.cs | ## 調べる | Scratch ブロック (日本語) | FUnity Unit クラス | UnitTitle | UnitCategory | 備考 | diff --git a/Runtime/Integrations/VisualScripting/FUnityScriptThreadManager.cs b/Runtime/Integrations/VisualScripting/FUnityScriptThreadManager.cs index c0e81af..72b690b 100644 --- a/Runtime/Integrations/VisualScripting/FUnityScriptThreadManager.cs +++ b/Runtime/Integrations/VisualScripting/FUnityScriptThreadManager.cs @@ -238,6 +238,8 @@ public string RegisterScratchThread(string actorId, ScriptGraphAsset graph, Coro var threadId = Guid.NewGuid().ToString("N"); + Debug.Log($"[FUnity.Thread] Register actor={actorId}, thread={threadId}"); + var info = new ScratchThreadInfo { ThreadId = threadId, @@ -269,6 +271,8 @@ public void UnregisterScratchThread(string threadId) /// public void StopAllScratchThreads() { + Debug.Log($"[FUnity.Thread] StopAll requested count={m_ScratchThreads.Count}"); + foreach (var info in m_ScratchThreads.Values) { if (info?.Coroutine == null) diff --git a/Runtime/Integrations/VisualScripting/Units/ScratchUnits/CloneUnits.cs b/Runtime/Integrations/VisualScripting/Units/ScratchUnits/CloneUnits.cs index e4545a5..700e91c 100644 --- a/Runtime/Integrations/VisualScripting/Units/ScratchUnits/CloneUnits.cs +++ b/Runtime/Integrations/VisualScripting/Units/ScratchUnits/CloneUnits.cs @@ -172,9 +172,7 @@ private void TriggerWithThreadRegistration(GraphReference reference, CloneEventA using (var flow = Flow.New(reference)) { var routine = RunEventCoroutine(flow, args); - var coroutine = FUnityScriptThreadManager.Instance.StartCoroutine(routine); - - ScratchUnitUtil.EnsureScratchThreadRegistered(flow, coroutine); + ScratchUnitUtil.StartScratchCoroutine(flow, routine); } } diff --git a/Runtime/Integrations/VisualScripting/Units/ScratchUnits/GreenFlagUnits.cs b/Runtime/Integrations/VisualScripting/Units/ScratchUnits/GreenFlagUnits.cs index baf644e..2a2f7b5 100644 --- a/Runtime/Integrations/VisualScripting/Units/ScratchUnits/GreenFlagUnits.cs +++ b/Runtime/Integrations/VisualScripting/Units/ScratchUnits/GreenFlagUnits.cs @@ -67,9 +67,7 @@ private void TriggerWithThreadRegistration(GraphReference reference, EmptyEventA using (var flow = Flow.New(reference)) { var routine = RunEventCoroutine(flow, args); - var coroutine = FUnityScriptThreadManager.Instance.StartCoroutine(routine); - - ScratchUnitUtil.EnsureScratchThreadRegistered(flow, coroutine); + ScratchUnitUtil.StartScratchCoroutine(flow, routine); } } diff --git a/Runtime/Integrations/VisualScripting/Units/ScratchUnits/InputEventUnits.cs b/Runtime/Integrations/VisualScripting/Units/ScratchUnits/InputEventUnits.cs index 8cb032e..5077b4d 100644 --- a/Runtime/Integrations/VisualScripting/Units/ScratchUnits/InputEventUnits.cs +++ b/Runtime/Integrations/VisualScripting/Units/ScratchUnits/InputEventUnits.cs @@ -94,9 +94,7 @@ private void TriggerWithThreadRegistration(GraphReference reference, EmptyEventA using (var flow = Flow.New(reference)) { var routine = RunEventCoroutine(flow, args); - var coroutine = FUnityScriptThreadManager.Instance.StartCoroutine(routine); - - ScratchUnitUtil.EnsureScratchThreadRegistered(flow, coroutine); + ScratchUnitUtil.StartScratchCoroutine(flow, routine); } } diff --git a/Runtime/Integrations/VisualScripting/Units/ScratchUnits/MessagingUnits.cs b/Runtime/Integrations/VisualScripting/Units/ScratchUnits/MessagingUnits.cs index 49ff8e3..082c189 100644 --- a/Runtime/Integrations/VisualScripting/Units/ScratchUnits/MessagingUnits.cs +++ b/Runtime/Integrations/VisualScripting/Units/ScratchUnits/MessagingUnits.cs @@ -205,9 +205,7 @@ private void TriggerWithThreadRegistration(GraphReference reference, MessagingCo using (var flow = Flow.New(reference)) { var routine = RunEventCoroutine(flow, args); - var coroutine = FUnityScriptThreadManager.Instance.StartCoroutine(routine); - - ScratchUnitUtil.EnsureScratchThreadRegistered(flow, coroutine); + ScratchUnitUtil.StartScratchCoroutine(flow, routine); } } diff --git a/Runtime/Integrations/VisualScripting/Units/ScratchUnits/ScratchUnitUtil.cs b/Runtime/Integrations/VisualScripting/Units/ScratchUnits/ScratchUnitUtil.cs index 7ace437..5d377d5 100644 --- a/Runtime/Integrations/VisualScripting/Units/ScratchUnits/ScratchUnitUtil.cs +++ b/Runtime/Integrations/VisualScripting/Units/ScratchUnits/ScratchUnitUtil.cs @@ -20,8 +20,7 @@ namespace FUnity.Runtime.Integrations.VisualScripting.Units.ScratchUnits public abstract class ScratchCoroutineUnitBase : Unit { /// - /// Visual Scripting 標準の ControlInputCoroutine を使って、 - /// IEnumerator ベースのコルーチン Unit を定義するためのヘルパーです。 + /// Scratch スレッド登録を挟みつつ、IEnumerator ベースのコルーチン Unit を定義するためのヘルパーです。 /// /// ControlInput のキー名。 /// Flow から IEnumerator を生成するファクトリ。 @@ -30,18 +29,30 @@ protected ControlInput CreateScratchCoroutineInput( string key, Func coroutineFactory) { - // この入力は「コルーチン」として扱われる。 - return ControlInputCoroutine(key, flow => + return ControlInput(key, flow => { if (coroutineFactory == null) { return null; } - // Unit 側で定義した IEnumerator をそのまま Visual Scripting に渡す。 - return coroutineFactory(flow); + var routine = coroutineFactory(flow); + StartScratchCoroutine(flow, routine); + + return null; }); } + + /// + /// Scratch スレッドとして扱うコルーチンを開始し、開始直後にスレッド登録を行います。 + /// + /// 現在のフロー情報。 + /// 実行するコルーチン。 + /// 開始したコルーチン参照。開始できない場合は null。 + protected Coroutine StartScratchCoroutine(Flow flow, IEnumerator routine) + { + return ScratchUnitUtil.StartScratchCoroutine(flow, routine); + } } /// @@ -232,6 +243,34 @@ public static void SetThreadContext(Flow flow, string actorId, Guid threadId) SetThreadContext(flow, actorId, threadId.ToString()); } + /// + /// Flow.StartCoroutine をラップし、Scratch スレッドの登録を確実に行うユーティリティです。 + /// + /// 現在のフロー情報。 + /// 実行するコルーチン。 + /// 開始したコルーチン参照。開始できない場合は null。 + public static Coroutine StartScratchCoroutine(Flow flow, IEnumerator routine) + { + if (flow == null || routine == null) + { + return null; + } + + var coroutine = flow.StartCoroutine(routine); + + var adapter = ResolveAdapter(flow); + ScriptGraphAsset graph = null; + + if (flow.stack?.machine is ScriptMachine machine) + { + graph = machine.nest?.macro as ScriptGraphAsset; + } + + EnsureScratchThreadRegistered(flow, adapter, graph, coroutine); + + return coroutine; + } + /// /// Scratch のイベント Unit から開始されたスレッドを FUnityScriptThreadManager に登録し、Flow.variables に俳優 ID とスレッド ID を保存します。 /// すでにフロー側にスレッド ID が設定されている場合は再登録せず、その ID を返します。 @@ -247,6 +286,8 @@ public static string EnsureScratchThreadRegistered( ScriptGraphAsset graph, Coroutine coroutine) { + Debug.Log("[FUnity.Thread] EnsureScratchThreadRegistered called"); + if (flow == null || coroutine == null) { return null;