using System; using System.Collections.Generic; using Cysharp.Threading.Tasks; using Sirenix.OdinInspector; using UnityEngine; using XNode; namespace Stary.Evo.StoryEditor { [Serializable,CreateNodeMenu("")] public class FlowNode : NodeBase { [HorizontalGroup("Port", order:0)] [Input] public Enter enter; [HorizontalGroup("Port")] [Output] public Exit exit; /// /// Exit端口连接的节点的执行类型 /// [BoxGroup("Config", order:5, showLabel:false)] [LabelText("后续执行")] public NodeExecuteType exitNodeExecuteType = NodeExecuteType.Async; /// /// 创建新的流程节点 /// /// 所在的块 /// 节点名称 /// 节点位置 /// 节点前部连接 /// 节点后部连接 public static T Create(NodeGraph graph, string name = null, Vector2 position = default, List prePorts = null, List nextPorts = null) where T:FlowNode { // 创建节点 var node = NodeBase.Create(graph, name, position); if (node == null) return null; // 将剧本与前部节点和后部节点相连 var enterPort = node.GetInputPort("enter"); if (enterPort != null && prePorts != null) prePorts.ForEach(port => port.Connect(enterPort)); var exitPort = node.GetInputPort("exit"); if (exitPort != null && nextPorts != null) nextPorts.ForEach(port => port.Connect(exitPort)); return node; } #region 工具方法 /// /// 将自身的入口连接传递给指定端口 /// /// 指定端口 /// 传递后删除自身连接 public void GiveEnterPortToOtherPort(NodePort otherPort, bool deleteSelf) => GiveConnectionToOtherPort(GetInputPort("enter"), otherPort, deleteSelf); /// /// 将自身的出口连接传递给指定端口 /// /// 指定端口 /// 传递后删除自身连接 public void GiveExitPortToOtherPort(NodePort otherPort, bool deleteSelf = false) => GiveConnectionToOtherPort(GetOutputPort("exit"), otherPort, deleteSelf); #endregion #region 节点操作 /// /// 向前插入节点 /// [HorizontalGroup("Insert", order:1)] [Button("(←)插入节点")] public void InsertForward() { // 生成新的空节点 var newNode = SelectionNode.Create(graph); // 将本节点的Enter连接给到新的节点的Enter GiveEnterPortToOtherPort(newNode.GetInputPort("enter"), true); // 将新的节点的Exit连接到本节点的Enter GetInputPort("enter").Connect(newNode.GetOutputPort("exit")); // 将新节点设定为本节点位置 newNode.position = position; // 将包括自身在内的所有后续节点向后移动一个默认间隔 newNode.DoActionToAllNodesAfter((thisNode, otherNode) => otherNode.position = thisNode.position + new Vector2(DefaultNodeXInterval, DefaultNodeYInterval)); } /// /// 向后插入节点 /// [HorizontalGroup("Insert")] [Button("插入节点(→)")] public void InsertBackward() { // 生成新的空节点 var newNode = SelectionNode.Create(graph); // 将本节点的Exit连接给到新的节点的Exit GiveExitPortToOtherPort(newNode.GetOutputPort("exit"), true); // 将新的节点的Enter连接到本节点的Exit GetOutputPort("exit").Connect(newNode.GetInputPort("enter")); // 将新节点设置为本节点位置后移一格 newNode.position = position + new Vector2(DefaultNodeXInterval, DefaultNodeYInterval); // 将所有后续节点向后移动一个默认间隔 newNode.DoActionToAllNodesAfter((thisNode, otherNode) => otherNode.position = thisNode.position + new Vector2(DefaultNodeXInterval, DefaultNodeYInterval)); } #endregion /// /// 导出 /// public new async UniTask Export() { FlowNodeData node = new(await base.Export()); node.executeType = exitNodeExecuteType; return node; } } }