CommandGraph
Узловая система визуального скриптинга, управляющая поведением NPC и событий — диалоги,
ветвления, выдача предметов/денег, телепорты, бои, квесты и другое. Каждый интерактивный
актёр владеет ActorCommandGraph; граф создаётся в редакторе и выполняется как корутина
во время выполнения.
Namespace: OpenMon.MCE.Actors.CommandGraph
Обычно графы команд строятся в визуальном редакторе (см.
руководство по CommandGraph), а не из C#. Приведённая
ниже рантайм-поверхность — это то, к чему вы обращаетесь при расширении системы
собственным узлом или программном запуске графа. Сами типы узлов (ShowDialog,
GivePlayerItem, TeleportPlayer, …) — это создаваемые ассеты: их поля сериализуются в
инспекторе, это не API для кода.
ActorCommandGraph
Контейнер графа одного актёра.
[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()
Именованные входные/выходные порты, которые узел предоставляет графу редактора. Линейный узел имеет один безымянный порт с каждой стороны; узел ветвления предоставляет по одному выходу на ветвь.
Возвращает: List<string>.
SingleExecutionPathCommandNode
Большинство узлов наследуются от SingleExecutionPathCommandNode — CommandNode с ровно
одним выходным портом (NextCommand). Узлы ветвления (If…, Switch…, While…) вместо
этого предоставляют несколько выходных портов.
public abstract class SingleExecutionPathCommandNode : CommandNode
{
public CommandNode NextCommand;
// GetOutputPorts() => один безымянный порт; 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;
}