134 lines
4.0 KiB
C#
134 lines
4.0 KiB
C#
using System;
|
||
using System.Linq;
|
||
using Cysharp.Threading.Tasks;
|
||
using UnityEngine;
|
||
using XNode;
|
||
|
||
namespace Stary.Evo.StoryEditor
|
||
{
|
||
[Serializable,CreateNodeMenu("")]
|
||
public class NodeBase : Node
|
||
{
|
||
[Serializable] public class Enter { }
|
||
[Serializable] public class Exit { }
|
||
|
||
/// <summary>
|
||
/// 默认节点位置间隔(x轴)
|
||
/// </summary>
|
||
public const float DefaultNodeXInterval = 250;
|
||
/// <summary>
|
||
/// 默认节点位置间隔(y轴)
|
||
/// </summary>
|
||
public const float DefaultNodeYInterval = 0;
|
||
|
||
/// <summary>
|
||
/// 创建新的节点
|
||
/// </summary>
|
||
/// <param name="graph">所在的块</param>
|
||
/// <param name="name">节点名称</param>
|
||
/// <param name="position">节点位置</param>
|
||
public static T Create<T>(NodeGraph graph, string name = null, Vector2 position = default) where T : NodeBase
|
||
{
|
||
// 创建节点
|
||
var node = graph.AddNode<T>();
|
||
|
||
if (node == null)
|
||
{
|
||
Debug.LogError("节点创建失败");
|
||
return null;
|
||
}
|
||
|
||
#if UNITY_EDITOR
|
||
// 将节点落盘
|
||
UnityEditor.AssetDatabase.AddObjectToAsset(node, graph);
|
||
UnityEditor.EditorUtility.SetDirty(graph);
|
||
#endif
|
||
|
||
// 设置节点变量
|
||
node.position = position;
|
||
node.name = name ?? $"{name}_para_sample";
|
||
|
||
// 初始化节点
|
||
node.Init();
|
||
|
||
return node;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 移除自身
|
||
/// </summary>
|
||
public void DestroySelf()
|
||
{
|
||
// 清理连接
|
||
ClearConnections();
|
||
// 移除与Graph之间的联系
|
||
if (graph)
|
||
{
|
||
graph.nodes.Remove(this);
|
||
#if UNITY_EDITOR
|
||
UnityEditor.AssetDatabase.RemoveObjectFromAsset(this);
|
||
#endif
|
||
}
|
||
// 销毁自身
|
||
DestroyImmediate(this);
|
||
}
|
||
|
||
public UniTask<NodeData> Export()
|
||
{
|
||
NodeData nodeData = new();
|
||
nodeData.name = name;
|
||
return UniTask.FromResult(nodeData);
|
||
}
|
||
|
||
#region 工具方法
|
||
|
||
/// <summary>
|
||
/// 将端口A的连接传递给端口B
|
||
/// </summary>
|
||
/// <param name="portA">端口A</param>
|
||
/// <param name="portB">端口B</param>
|
||
/// <param name="deleteA">移除端口A的连接</param>
|
||
public static void GiveConnectionToOtherPort(NodePort portA, NodePort portB, bool deleteA = false)
|
||
{
|
||
// 排除端口A与端口B重合的情况
|
||
if (portA == portB)
|
||
return;
|
||
|
||
// 获取当前Enter端口的所有连接
|
||
var enterPorts = portA.GetConnections();
|
||
|
||
enterPorts.ForEach(port =>
|
||
{
|
||
// 将Enter端口与该端口断开
|
||
if (deleteA)
|
||
port.Disconnect(portA);
|
||
// 将指定的端口与该端口连接
|
||
port.Connect(portB);
|
||
});
|
||
}
|
||
|
||
/// <summary>
|
||
/// 对所有之后的节点执行动作
|
||
/// </summary>
|
||
/// <param name="action">指定动作</param>
|
||
public void DoActionToAllNodesAfter(Action<NodeBase, NodeBase> action)
|
||
{
|
||
// 所有出口端口
|
||
Ports.Where(p => p.IsOutput).ToList().ForEach(port =>
|
||
{
|
||
// 所有出口端口连接的所有端口
|
||
port.GetConnections().ForEach(otherSide =>
|
||
{
|
||
// 所有出口端口连接的所有端口的是NodeBase的节点
|
||
if (otherSide.node is NodeBase baseNode)
|
||
{
|
||
action?.Invoke(this, baseNode);
|
||
baseNode.DoActionToAllNodesAfter(action);
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
#endregion
|
||
}
|
||
} |