メインコンテンツまでスキップ

CommandGraph

NPC やイベントの挙動を駆動するノードベースのビジュアルスクリプティングシステムです。 会話、分岐、アイテム/お金の付与、ワープ、バトル、クエストなどを扱います。操作可能な各アクターは ActorCommandGraph を保持し、グラフはエディタで作成され、実行時にコルーチンとして実行されます。

Namespace: OpenMon.MCE.Actors.CommandGraph

エディタで作成し、実行時に走らせる

通常、コマンドグラフは C# からではなくビジュアルエディタで構築します (CommandGraph ガイドを参照)。以下の実行時サーフェスは、 カスタムノードでシステムを拡張したり、グラフをプログラムで実行したりするときに触れるものです。 ノード型そのもの(ShowDialog、GivePlayerItem、TeleportPlayer など)は作成済みアセットで、 そのフィールドはインスペクタでシリアライズされ、コード向けの API ではありません。

ActorCommandGraph​

1 つのアクターのグラフのコンテナ。

[Serializable]
public class ActorCommandGraph
{
public bool IsRunning { get; }

[SerializeReference] public CommandNode RootNode;
[SerializeReference] public List<CommandNode> Nodes;

public bool IsGraphEmpty { get; }

public IEnumerator Run(CommandParameterData parameterData,
Action<bool> onLoopRunningUpdatedCallback = null);

public CommandNode CreateNode(Type type, Vector2 position = default);
public void DeleteNode(CommandNode node);
public void ConnectNodes(CommandNode parent, CommandNode child, int parentIndex);
public void RemoveConnection(CommandNode parent, CommandNode child, int parentIndex);
public List<CommandNode> GetChildren(CommandNode node);
}

IsRunning​

このグラフが現在実行中か。

型: bool(読み取り専用)

RootNode​

実行が開始する入口の CommandNode(RootNode)。ポリモーフィックなノード型が往復できるよう、 参照でシリアライズされます。

型: CommandNode

Nodes​

RootNode から到達できないノードも含む、グラフ内のすべてのノード(エディタが孤立/未接続の ノードを永続化できるよう保持)。

型: List<CommandNode>

IsGraphEmpty​

ルートノードがない、またはルートに子がないとき true。

型: bool(読み取り専用)

Run(CommandParameterData parameterData, Action<bool> onLoopRunningUpdatedCallback = null)​

グラフを実行します。IsRunning をセットし、RootNode.RunCommandAndContinue を実行して、 CommandParameterData のコンテキストを各ノードにスレッドします。

戻り値: IEnumerator — コルーチンから yield してください。

CreateNode(Type type, Vector2 position = default) / DeleteNode / ConnectNodes / RemoveConnection​

エディタ向けのグラフ変更: CommandNode サブクラスのノードを生成、削除、出力ポートインデックスで 親→子の接続を配線/解除します。

CommandNode​

すべてのノード型が派生する抽象基底クラス。

[Serializable]
public abstract class CommandNode : MonsterDatabaseData<CommandNode>
{
public bool IsRunning { get; }
public string name;
public string GUID;
public Vector2 Position;
public Action OnPortsUpdated;

public virtual IEnumerator RunCommandAndContinue(CommandParameterData parameterData);

protected abstract IEnumerator Run(CommandParameterData parameterData,
Action<CommandParameterData> callback);

public abstract List<string> GetInputPorts();
public abstract List<string> GetOutputPorts();
public abstract void AddChild(CommandNode child, int index);
public abstract void RemoveChild(CommandNode child, int index);
public abstract List<CommandNode> GetChildren();
public abstract List<CommandNode> GetIndexedChildren();
}

RunCommandAndContinue(CommandParameterData parameterData)​

このノードを(抽象 Run 経由で)実行し、その子へ続きます。グラフがループ実行のときの ループゲーティングを扱います。

Run(CommandParameterData parameterData, Action<CommandParameterData> callback)​

protected abstract — ノードの実処理。カスタムノードでこれをオーバーライドします。 完了時に(変更後の可能性がある)パラメータデータで callback を呼びます。

GetInputPorts() / GetOutputPorts()​

ノードがエディタグラフに公開する名前付き入力/出力ポート。線形ノードは各側に名前なしポートを 1 つ持ち、分岐ノードは分岐ごとに 1 つの出力を公開します。

戻り値: List<string>。

SingleExecutionPathCommandNode​

ほとんどのノードは SingleExecutionPathCommandNode から派生します。これは出力ポートが ちょうど 1 つ(NextCommand)の CommandNode です。分岐ノード(If…、Switch…、While…)は 代わりに複数の出力ポートを公開します。

public abstract class SingleExecutionPathCommandNode : CommandNode
{
public CommandNode NextCommand;
// GetOutputPorts() => 名前なしポート 1 つ; AddChild が NextCommand を設定。
}

CommandParameterData​

実行中に各ノードへスレッドされる実行コンテキスト。カスタムノードが読み書きするサーフェスです。

public class CommandParameterData
{
public ActorCommandGraph Graph;
public GameObject Owner;
public Actor Actor;
public MCECharacterController.Direction PlayerDirection;
public PlayerCharacter PlayerCharacter;
public GlobalGameData GlobalGameData;
public MCESettings MCESettings;
public MonsterDatabaseInstance MonsterDatabase;
public IBattleLauncher BattleLauncher;
public ILocalizer Localizer;
public IConfigurationManager ConfigurationManager;
public IInputManager InputManager;
public PlayerTeleporter Teleporter;
public SavegameManager SavegameManager;
public MapSceneLauncher MapSceneLauncher;
public TimeManager TimeManager;
public QuestManager QuestManager;
public TradeManager TradeManager;
public bool UsingMove;
public MonsterInstance MoveUser;
public Move Move;
public bool IsRunningOnLoop;
public ICommandParameter[] ExtraParams;
public Action<CommandCallbackParams> Callback;
}

組み込みノードのカテゴリ​

ノードは Actors/CommandGraph/ 配下のフォルダごとに分類されます。代表的な型:

カテゴリノード例
DialogsShowDialog, ShowChoiceDialog, ShowSignDialog, NextDialog
ItemsGivePlayerItem, GivePlayerMoney, IfPlayerHasItem, ChooseItemDialog
MonstersGiveMonsters, HealPlayerRoster, ChooseMonsterDialog, ChangeMonsterNickname
BattlesSingleWildFight, SingleTrainerFight, DoubleWildFight, StartTowerRun
BadgesGiveBadge, IfPlayerHasBadge
DexGiveDex, RegisterMonsterAsSeen, IfDexIsComplete
QuestsStartQuest, CompleteQuest, ProgressQuestObjective, IfCompletedQuest
VariablesSetBoolVariable, SetIntVariable, IfBool, IfCondition, WhileBool
UtilsTeleportPlayer, WaitTime, AutoSaveIfEnabled, SwitchTimeOfDay
AnimationsMove, Look, LookAtPlayer, WalkToPlayer, FadeScreenToBlack
Shops / TradeBuyInShop, SellInShop, TradeSelectedMonster

カスタムノードを書く​

using System;
using System.Collections;
using System.Collections.Generic;
using OpenMon.MCE.Actors.CommandGraph;

namespace MyGame.Events
{
[Serializable]
public class LogStepsTaken : SingleExecutionPathCommandNode
{
protected override IEnumerator Run(CommandParameterData parameterData,
Action<CommandParameterData> callback)
{
// グラフがスレッドする共有コンテキストから読み取ります。
uint steps = parameterData.GlobalGameData.StepsTaken;
UnityEngine.Debug.Log($"Player has taken {steps} steps.");

callback(parameterData);
yield break;
}
}
}