【a】可视化剧本编辑器 10.StoryEditor
This commit is contained in:
128
Assets/10.StoryEditor/RunTime/VisualEditor/Node/FlowNode.cs
Normal file
128
Assets/10.StoryEditor/RunTime/VisualEditor/Node/FlowNode.cs
Normal file
@@ -0,0 +1,128 @@
|
||||
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;
|
||||
|
||||
/// <summary>
|
||||
/// Exit端口连接的节点的执行类型
|
||||
/// </summary>
|
||||
[BoxGroup("Config", order:5, showLabel:false)]
|
||||
[LabelText("后续执行")]
|
||||
public NodeExecuteType exitNodeExecuteType = NodeExecuteType.Async;
|
||||
|
||||
/// <summary>
|
||||
/// 创建新的流程节点
|
||||
/// </summary>
|
||||
/// <param name="graph">所在的块</param>
|
||||
/// <param name="name">节点名称</param>
|
||||
/// <param name="position">节点位置</param>
|
||||
/// <param name="prePorts">节点前部连接</param>
|
||||
/// <param name="nextPorts">节点后部连接</param>
|
||||
public static T Create<T>(NodeGraph graph, string name = null, Vector2 position = default,
|
||||
List<NodePort> prePorts = null, List<NodePort> nextPorts = null) where T:FlowNode
|
||||
{
|
||||
// 创建节点
|
||||
var node = NodeBase.Create<T>(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 工具方法
|
||||
|
||||
/// <summary>
|
||||
/// 将自身的入口连接传递给指定端口
|
||||
/// </summary>
|
||||
/// <param name="otherPort">指定端口</param>
|
||||
/// <param name="deleteSelf">传递后删除自身连接</param>
|
||||
public void GiveEnterPortToOtherPort(NodePort otherPort, bool deleteSelf)
|
||||
=> GiveConnectionToOtherPort(GetInputPort("enter"), otherPort, deleteSelf);
|
||||
|
||||
/// <summary>
|
||||
/// 将自身的出口连接传递给指定端口
|
||||
/// </summary>
|
||||
/// <param name="otherPort">指定端口</param>
|
||||
/// <param name="deleteSelf">传递后删除自身连接</param>
|
||||
public void GiveExitPortToOtherPort(NodePort otherPort, bool deleteSelf = false)
|
||||
=> GiveConnectionToOtherPort(GetOutputPort("exit"), otherPort, deleteSelf);
|
||||
|
||||
#endregion
|
||||
|
||||
#region 节点操作
|
||||
|
||||
/// <summary>
|
||||
/// 向前插入节点
|
||||
/// </summary>
|
||||
[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));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 向后插入节点
|
||||
/// </summary>
|
||||
[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
|
||||
|
||||
/// <summary>
|
||||
/// 导出
|
||||
/// </summary>
|
||||
public new async UniTask<FlowNodeData> Export()
|
||||
{
|
||||
FlowNodeData node = new(await base.Export());
|
||||
node.executeType = exitNodeExecuteType;
|
||||
return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user