CommandGraph
El sistema de scripting visual basado en nodos que dirige el comportamiento de NPCs y
eventos: dialogos, ramas, entrega de objetos/dinero, teletransportes, combates, misiones
y mas. Cada actor interactuable posee un ActorCommandGraph; el grafo se edita en el
editor y se ejecuta como una corrutina en tiempo de ejecucion.
Namespace: OpenMon.MCE.Actors.CommandGraph
Normalmente construis los grafos de comandos en el editor visual (ver la
guia de CommandGraph), no desde C#. La superficie de
runtime de abajo es la que tocas al extender el sistema con un nodo personalizado o
al ejecutar un grafo programaticamente. Los tipos de nodo (ShowDialog, GivePlayerItem,
TeleportPlayer, …) son assets editados: sus campos se serializan en el inspector, no
son una API para codigo.
ActorCommandGraph
El contenedor del grafo de un actor.
[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
Si este grafo se esta ejecutando actualmente.
Tipo: bool (solo lectura)
RootNode
El CommandNode de entrada (un RootNode) desde el que arranca la ejecucion. Serializado
por referencia para que los tipos polimorficos de nodo persistan correctamente.
Tipo: CommandNode
Nodes
Todos los nodos del grafo, incluidos los no alcanzables desde RootNode (se guardan para
que el editor pueda persistir nodos huerfanos/desconectados).
Tipo: List<CommandNode>
IsGraphEmpty
true cuando no hay nodo raiz o la raiz no tiene hijos.
Tipo: bool (solo lectura)
Run(CommandParameterData parameterData, Action<bool> onLoopRunningUpdatedCallback = null)
Ejecuta el grafo. Pone IsRunning, luego corre RootNode.RunCommandAndContinue,
hilando un CommandParameterData de contexto por cada nodo.
Devuelve: IEnumerator — cedelo (yield) desde una corrutina.
CreateNode(Type type, Vector2 position = default) / DeleteNode / ConnectNodes / RemoveConnection
Mutacion del grafo para el editor: instanciar un nodo de una subclase de CommandNode,
eliminarlo, y conectar/desconectar relaciones padre→hijo por indice de puerto de salida.
CommandNode
La clase base abstracta de la que deriva cada tipo de nodo.
[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)
Ejecuta este nodo (via el Run abstracto) y luego continua hacia sus hijos. Maneja el
bloqueo por bucle cuando el grafo corre en loop.
Run(CommandParameterData parameterData, Action<CommandParameterData> callback)
protected abstract — el trabajo real del nodo. Sobrescribilo en un nodo propio.
Llama a callback con los datos de parametros (posiblemente modificados) al terminar.
GetInputPorts() / GetOutputPorts()
Los puertos de entrada/salida con nombre que el nodo expone al grafo del editor. Un nodo lineal tiene un unico puerto sin nombre en cada lado; un nodo de rama expone una salida por rama.
Devuelve: List<string>.
SingleExecutionPathCommandNode
La mayoria de los nodos deriva de SingleExecutionPathCommandNode, un CommandNode con
exactamente un puerto de salida (NextCommand). Los nodos de rama (If…, Switch…,
While…) exponen en cambio multiples puertos de salida.
public abstract class SingleExecutionPathCommandNode : CommandNode
{
public CommandNode NextCommand;
// GetOutputPorts() => un puerto sin nombre; AddChild asigna NextCommand.
}
CommandParameterData
El contexto de ejecucion hilado por cada nodo durante una corrida: la superficie que un nodo propio lee y escribe.
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;
}
Categorias de nodos integrados
Los nodos se agrupan por carpeta bajo Actors/CommandGraph/. Tipos representativos:
| Categoria | Nodos de ejemplo |
|---|---|
| Dialogs | ShowDialog, ShowChoiceDialog, ShowSignDialog, NextDialog |
| Items | GivePlayerItem, GivePlayerMoney, IfPlayerHasItem, ChooseItemDialog |
| Monsters | GiveMonsters, HealPlayerRoster, ChooseMonsterDialog, ChangeMonsterNickname |
| Battles | SingleWildFight, SingleTrainerFight, DoubleWildFight, StartTowerRun |
| Badges | GiveBadge, IfPlayerHasBadge |
| Dex | GiveDex, RegisterMonsterAsSeen, IfDexIsComplete |
| Quests | StartQuest, CompleteQuest, ProgressQuestObjective, IfCompletedQuest |
| Variables | SetBoolVariable, SetIntVariable, IfBool, IfCondition, WhileBool |
| Utils | TeleportPlayer, WaitTime, AutoSaveIfEnabled, SwitchTimeOfDay |
| Animations | Move, Look, LookAtPlayer, WalkToPlayer, FadeScreenToBlack |
| Shops / Trade | BuyInShop, SellInShop, TradeSelectedMonster |
Escribir un nodo personalizado
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)
{
// Lee del contexto compartido hilado por el grafo.
uint steps = parameterData.GlobalGameData.StepsTaken;
UnityEngine.Debug.Log($"Player has taken {steps} steps.");
callback(parameterData);
yield break;
}
}
}