diff --git a/Docs/VS_Scratch_Mapping.md b/Docs/VS_Scratch_Mapping.md
index 7a7bab1..9c558f5 100644
--- a/Docs/VS_Scratch_Mapping.md
+++ b/Docs/VS_Scratch_Mapping.md
@@ -37,6 +37,9 @@ Scratch ブロックと FUnity 独自 Visual Scripting Unit の対応関係で
## 見た目
| Scratch ブロック (日本語) | FUnity Unit クラス | UnitTitle | UnitCategory | 備考 |
| --- | --- | --- | --- | --- |
+| コスチュームを○にする | FUnity.Runtime.Integrations.VisualScripting.Units.ScratchUnits.SetCostumeNumberUnit | コスチュームを○にする | FUnity/Scratch/見た目 | コスチューム番号を絶対設定。定義: Runtime/.../CostumeUnits.cs |
+| 次のコスチュームにする | FUnity.Runtime.Integrations.VisualScripting.Units.ScratchUnits.NextCostumeUnit | 次のコスチュームにする | FUnity/Scratch/見た目 | コスチュームを循環切替。定義: Runtime/.../CostumeUnits.cs |
+| コスチュームの番号 | FUnity.Runtime.Integrations.VisualScripting.Units.ScratchUnits.GetCostumeNumberUnit | コスチュームの番号 | FUnity/Scratch/見た目 | 現在の番号を取得。定義: Runtime/.../CostumeUnits.cs |
| 大きさを○%にする | FUnity.Runtime.Integrations.VisualScripting.Units.ScratchUnits.SetSizePercentUnit | 大きさを○%にする | FUnity/Scratch/見た目 | 拡大率を絶対設定。定義: Runtime/.../SizeUnits.cs |
| 大きさを○%ずつ変える | FUnity.Runtime.Integrations.VisualScripting.Units.ScratchUnits.ChangeSizeByPercentUnit | 大きさを○%ずつ変える | FUnity/Scratch/見た目 | 拡大率を相対変更。定義: Runtime/.../SizeUnits.cs |
| ○と○秒言う | FUnity.Runtime.Integrations.VisualScripting.Units.ScratchUnits.SayForSecondsUnit | ○と○秒言う | FUnity/Scratch/見た目 | 指定秒数で吹き出し表示。定義: Runtime/.../SpeechUnits.cs |
diff --git a/Runtime/Integrations/VisualScripting/Units/ScratchUnits/CostumeUnits.cs b/Runtime/Integrations/VisualScripting/Units/ScratchUnits/CostumeUnits.cs
new file mode 100644
index 0000000..331eed9
--- /dev/null
+++ b/Runtime/Integrations/VisualScripting/Units/ScratchUnits/CostumeUnits.cs
@@ -0,0 +1,235 @@
+// Updated: 2025-05-22
+using System.Collections;
+using UnityEngine;
+using Unity.VisualScripting;
+using FUnity.Runtime.Integrations.VisualScripting;
+using FUnity.Runtime.Presenter;
+
+namespace FUnity.Runtime.Integrations.VisualScripting.Units.ScratchUnits
+{
+ ///
+ /// Scratch の「コスチュームを ◯ にする」ブロックに対応し、Presenter を通じてコスチューム番号を絶対設定する Visual Scripting Unit です。
+ ///
+ [UnitTitle("コスチュームを○にする")]
+ [UnitCategory("FUnity/Scratch/見た目")]
+ [UnitSubtitle("funity scratch 見た目 costume set コスチューム")]
+ [TypeIcon(typeof(FUnityScratchUnitIcon))]
+ public sealed class SetCostumeNumberUnit : Unit
+ {
+ /// ログ出力に利用するユニット名です。
+ private const string UnitName = "コスチュームを○にする";
+
+ /// 制御フローを受け取る ControlInput です。
+ [DoNotSerialize]
+ private ControlInput m_Enter;
+
+ /// 後続へ制御を渡す ControlOutput です。
+ [DoNotSerialize]
+ private ControlOutput m_Exit;
+
+ /// 1 始まりのコスチューム番号を受け取る ValueInput です。
+ [DoNotSerialize]
+ private ValueInput m_CostumeNumber;
+
+ /// enter ポートへの参照です。
+ public ControlInput Enter => m_Enter;
+
+ /// exit ポートへの参照です。
+ public ControlOutput Exit => m_Exit;
+
+ /// costumeNumber ポートへの参照です。
+ public ValueInput CostumeNumber => m_CostumeNumber;
+
+ ///
+ /// ポート定義を行い、enter→exit の制御線とコスチューム番号入力を登録します。
+ ///
+ protected override void Definition()
+ {
+ m_Enter = ControlInputCoroutine("enter", Run);
+ m_Exit = ControlOutput("exit");
+ m_CostumeNumber = ValueInput("costumeNumber", 1);
+
+ Succession(m_Enter, m_Exit);
+ }
+
+ ///
+ /// フロー入力時に Presenter を解決し、指定されたコスチューム番号を適用します。
+ ///
+ /// 現在のフロー情報。
+ /// exit ポートへ制御を渡す列挙子。
+ private IEnumerator Run(Flow flow)
+ {
+ if (!CostumeUnitUtil.TryResolvePresenter(flow, UnitName, out var presenter))
+ {
+ yield return m_Exit;
+ yield break;
+ }
+
+ var spriteCount = presenter.SpriteCount;
+ if (spriteCount <= 0)
+ {
+ presenter.SetSpriteIndex(0);
+ yield return m_Exit;
+ yield break;
+ }
+
+ var costumeNumber = flow.GetValue(m_CostumeNumber);
+ var clampedNumber = Mathf.Clamp(costumeNumber, 1, spriteCount);
+ var index0 = clampedNumber - 1;
+
+ presenter.SetSpriteIndex(index0);
+ yield return m_Exit;
+ }
+ }
+
+ ///
+ /// Scratch の「次のコスチュームにする」ブロックに対応し、コスチュームを循環的に切り替える Visual Scripting Unit です。
+ ///
+ [UnitTitle("次のコスチュームにする")]
+ [UnitCategory("FUnity/Scratch/見た目")]
+ [UnitSubtitle("funity scratch 見た目 costume next 次へ")]
+ [TypeIcon(typeof(FUnityScratchUnitIcon))]
+ public sealed class NextCostumeUnit : Unit
+ {
+ /// ログ出力に利用するユニット名です。
+ private const string UnitName = "次のコスチュームにする";
+
+ /// 制御フローを受け取る ControlInput です。
+ [DoNotSerialize]
+ private ControlInput m_Enter;
+
+ /// 後続へ制御を渡す ControlOutput です。
+ [DoNotSerialize]
+ private ControlOutput m_Exit;
+
+ /// enter ポートへの参照です。
+ public ControlInput Enter => m_Enter;
+
+ /// exit ポートへの参照です。
+ public ControlOutput Exit => m_Exit;
+
+ ///
+ /// ポート定義を行い、enter→exit の制御線のみを登録します。
+ ///
+ protected override void Definition()
+ {
+ m_Enter = ControlInputCoroutine("enter", Run);
+ m_Exit = ControlOutput("exit");
+
+ Succession(m_Enter, m_Exit);
+ }
+
+ ///
+ /// フロー入力時に Presenter を解決し、次のコスチュームへ循環的に切り替えます。
+ ///
+ /// 現在のフロー情報。
+ /// exit ポートへ制御を渡す列挙子。
+ private IEnumerator Run(Flow flow)
+ {
+ if (!CostumeUnitUtil.TryResolvePresenter(flow, UnitName, out var presenter))
+ {
+ yield return m_Exit;
+ yield break;
+ }
+
+ var spriteCount = presenter.SpriteCount;
+ if (spriteCount <= 0)
+ {
+ presenter.SetSpriteIndex(0);
+ yield return m_Exit;
+ yield break;
+ }
+
+ var current = presenter.SpriteIndex;
+ var safeCurrent = Mathf.Clamp(current, 0, spriteCount - 1);
+ var next = (safeCurrent + 1) % spriteCount;
+
+ presenter.SetSpriteIndex(next);
+ yield return m_Exit;
+ }
+ }
+
+ ///
+ /// Scratch の「コスチュームの番号」ブロックに対応し、現在のコスチューム番号(1 始まり)を取得する Visual Scripting Unit です。
+ ///
+ [UnitTitle("コスチュームの番号")]
+ [UnitCategory("FUnity/Scratch/見た目")]
+ [UnitSubtitle("funity scratch 見た目 costume number 番号")]
+ [TypeIcon(typeof(FUnityScratchUnitIcon))]
+ public sealed class GetCostumeNumberUnit : Unit
+ {
+ /// ログ出力に利用するユニット名です。
+ private const string UnitName = "コスチュームの番号";
+
+ /// 現在のコスチューム番号を出力する ValueOutput です。
+ [DoNotSerialize]
+ private ValueOutput m_CostumeNumber;
+
+ /// costumeNumber ポートへの参照です。
+ public ValueOutput CostumeNumber => m_CostumeNumber;
+
+ ///
+ /// ポート定義を行い、現在のコスチューム番号を返す ValueOutput を登録します。
+ ///
+ protected override void Definition()
+ {
+ m_CostumeNumber = ValueOutput("costumeNumber", GetCostumeNumber);
+ }
+
+ ///
+ /// Presenter を解決して現在のコスチューム番号(1 始まり)を返します。
+ ///
+ /// 現在のフロー情報。
+ /// 1 始まりで表現したコスチューム番号。利用可能な Sprite が無い場合は 0。
+ private int GetCostumeNumber(Flow flow)
+ {
+ if (!CostumeUnitUtil.TryResolvePresenter(flow, UnitName, out var presenter))
+ {
+ return 0;
+ }
+
+ var spriteCount = presenter.SpriteCount;
+ if (spriteCount <= 0)
+ {
+ return 0;
+ }
+
+ var index0 = Mathf.Clamp(presenter.SpriteIndex, 0, spriteCount - 1);
+ return index0 + 1;
+ }
+ }
+
+ ///
+ /// コスチューム系ユニットで共通利用する Presenter 解決ロジックをまとめたユーティリティです。
+ ///
+ internal static class CostumeUnitUtil
+ {
+ ///
+ /// ActorPresenterAdapter および ActorPresenter を解決し、失敗時には警告ログを出力します。
+ ///
+ /// 現在のフロー情報。
+ /// ログ出力に使用するユニット名。
+ /// 解決できた Presenter。失敗時は null。
+ /// 解決に成功した場合は true。
+ public static bool TryResolvePresenter(Flow flow, string unitName, out ActorPresenter presenter)
+ {
+ presenter = null;
+
+ var adapter = ScratchUnitUtil.ResolveAdapter(flow);
+ if (adapter == null)
+ {
+ Debug.LogWarning($"[FUnity] Scratch/Looks/{unitName}: ActorPresenterAdapter を自動解決できません。ScriptMachine の Variables 設定を確認してください。");
+ return false;
+ }
+
+ presenter = adapter.Presenter;
+ if (presenter == null)
+ {
+ Debug.LogWarning($"[FUnity] Scratch/Looks/{unitName}: ActorPresenter が未接続のためコスチュームを処理できません。Adapter と Presenter の紐付けを確認してください。");
+ return false;
+ }
+
+ return true;
+ }
+ }
+}
diff --git a/Runtime/Integrations/VisualScripting/Units/ScratchUnits/CostumeUnits.cs.meta b/Runtime/Integrations/VisualScripting/Units/ScratchUnits/CostumeUnits.cs.meta
new file mode 100644
index 0000000..11b8ecc
--- /dev/null
+++ b/Runtime/Integrations/VisualScripting/Units/ScratchUnits/CostumeUnits.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: ffb3ccd41ff7495cb4b0f1fabbf42585