Gameplay Ingredients是一组用于 Unity 游戏的运行时和编辑器工具:一组脚本的集合,可在制作游戏和原型时简化简单的任务。
您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

201 行
4.6 KiB

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using System;
namespace GraphProcessor
{
[System.Serializable]
public class BaseGraph : ScriptableObject, ISerializationCallbackReceiver
{
static readonly int maxComputeOrderDepth = 1000;
//JSon datas contaning all elements of the graph
[SerializeField]
public List< JsonElement > serializedNodes = new List< JsonElement >();
[System.NonSerialized]
public List< BaseNode > nodes = new List< BaseNode >();
[System.NonSerialized]
public Dictionary< string, BaseNode > nodesPerGUID = new Dictionary< string, BaseNode >();
[SerializeField]
public List< SerializableEdge > edges = new List< SerializableEdge >();
[System.NonSerialized]
public Dictionary< string, SerializableEdge > edgesPerGUID = new Dictionary< string, SerializableEdge >();
[SerializeField]
public List< CommentBlock > commentBlocks = new List< CommentBlock >();
[SerializeField]
public List< PinnedElement > pinnedWindows = new List< PinnedElement >();
[System.NonSerialized]
Dictionary< BaseNode, int > computeOrderDictionary = new Dictionary< BaseNode, int >();
//graph visual properties
public Vector3 position = Vector3.zero;
public Vector3 scale = Vector3.one;
void OnEnable()
{
DestroyBrokenGraphElements();
UpdateComputeOrder();
}
public void AddNode(BaseNode node)
{
nodes.Add(node);
}
public void RemoveNode(BaseNode node)
{
nodes.Remove(node);
}
public SerializableEdge Connect(BaseNode inputNode, string inputFieldName, BaseNode outputNode, string outputFieldName)
{
var edge = SerializableEdge.CreateNewEdge(this, inputNode, inputFieldName, outputNode, outputFieldName);
edges.Add(edge);
return edge;
}
public void Disconnect(BaseNode inputNode, string inputFieldName, BaseNode outputNode, string outputFieldName)
{
edges.RemoveAll(r => r.inputNode == inputNode
&& r.outputNode == outputNode
&& r.outputFieldName == outputFieldName
&& r.inputFieldName == inputFieldName
);
}
public void Disconnect(string edgeGUID)
{
edges.RemoveAll(r => r.GUID == edgeGUID);
}
public void AddCommentBlock(CommentBlock block)
{
commentBlocks.Add(block);
}
public void RemoveCommentBlock(CommentBlock block)
{
commentBlocks.Remove(block);
}
public PinnedElement OpenPinned(Type viewType)
{
var pinned = pinnedWindows.Find(p => p.editorType.type == viewType);
if (pinned == null)
{
pinned = new PinnedElement(viewType);
pinnedWindows.Add(pinned);
}
else
pinned.opened = true;
return pinned;
}
public void ClosePinned(Type viewType)
{
var pinned = pinnedWindows.Find(p => p.editorType.type == viewType);
pinned.opened = false;
}
public void OnBeforeSerialize()
{
serializedNodes.Clear();
foreach (var node in nodes)
serializedNodes.Add(JsonSerializer.Serialize(node));
}
public void OnAfterDeserialize()
{
nodes.Clear();
foreach (var serializedNode in serializedNodes)
{
var node = JsonSerializer.DeserializeNode(serializedNode) as BaseNode;
nodes.Add(node);
nodesPerGUID[node.GUID] = node;
}
foreach (var edge in edges)
{
edge.Deserialize();
edgesPerGUID[edge.GUID] = edge;
}
}
public void UpdateComputeOrder()
{
if (nodes.Count == 0)
return ;
computeOrderDictionary.Clear();
foreach (var node in nodes)
UpdateComputeOrder(0, node);
}
int UpdateComputeOrder(int depth, BaseNode node)
{
int computeOrder = 0;
if (depth > maxComputeOrderDepth)
{
Debug.LogError("Recursion error while updating compute order");
return -1;
}
if (computeOrderDictionary.ContainsKey(node))
return node.computeOrder;
if (!node.canProcess)
{
node.computeOrder = -1;
computeOrderDictionary[node] = -1;
return -1;
}
foreach (var dep in node.GetInputNodes())
{
int c = UpdateComputeOrder(depth + 1, dep);
if (c == -1)
{
computeOrder = -1;
break ;
}
computeOrder += c;
}
if (computeOrder != -1)
computeOrder++;
node.computeOrder = computeOrder;
computeOrderDictionary[node] = computeOrder;
return computeOrder;
}
void DestroyBrokenGraphElements()
{
edges.RemoveAll(e => e.inputNode == null
|| e.outputNode == null
|| string.IsNullOrEmpty(e.outputFieldName)
|| string.IsNullOrEmpty(e.inputFieldName)
);
nodes.RemoveAll(n => n == null);
}
}
}