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;