您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

242 行
9.3 KiB

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;
using UnityEngine.Graphing;
namespace UnityEditor.Graphing.Drawing
{
[AttributeUsage(AttributeTargets.Class)]
sealed class CustomNodeUI : Attribute
{
private Type m_ModeToDrawFor;
public CustomNodeUI(Type nodeToDrawFor)
{
m_ModeToDrawFor = nodeToDrawFor;
}
public Type nodeToDrawFor
{
get { return m_ModeToDrawFor; } }
}
/*
public class GraphDataSource : ICanvasDataSource
{
readonly List<DrawableNode> m_DrawableNodes = new List<DrawableNode>();
public IGraphAsset graphAsset { get; set; }
public ICollection<DrawableNode> lastGeneratedNodes
{
get { return m_DrawableNodes; }
}
private static Type[] GetTypesFromAssembly(Assembly assembly)
{
if (assembly == null)
return new Type[] {};
try
{
return assembly.GetTypes();
}
catch (ReflectionTypeLoadException)
{
return new Type[] {};
}
}
private static Dictionary<Type, Type> s_DrawerUI;
private static Dictionary<Type, Type> drawerUI
{
get
{
if (s_DrawerUI == null)
{
s_DrawerUI = new Dictionary<Type, Type>();
var loadedTypes = AppDomain.CurrentDomain.GetAssemblies().SelectMany(x => GetTypesFromAssembly(x));
foreach (var type in loadedTypes)
{
var attribute = type.GetCustomAttributes(true).OfType<CustomNodeUI>().FirstOrDefault();
if (attribute != null && typeof(ICustomNodeUi).IsAssignableFrom(type))
s_DrawerUI.Add(attribute.nodeToDrawFor, type);
}
}
return s_DrawerUI;
}
}
public CanvasElement[] FetchElements()
{
m_DrawableNodes.Clear();
var graph = graphAsset.graph;
Debug.LogFormat("Trying to convert: {0}", graphAsset.graph);
foreach (var node in graph.GetNodes<INode>())
{
var nodeType = node.GetType();
Type draweruiType = null;
while (draweruiType == null && nodeType != null)
{
draweruiType = drawerUI.FirstOrDefault(x => x.Key == nodeType).Value;
nodeType = nodeType.BaseType;
}
ICustomNodeUi customUI = null;
if (draweruiType != null)
{
try
{
customUI = Activator.CreateInstance(draweruiType) as ICustomNodeUi;
customUI.node = node;
}
catch (Exception e)
{
Debug.LogWarningFormat("Could not construct instance of: {0} - {1}", draweruiType, e);
}
}
// add the nodes
m_DrawableNodes.Add(new DrawableNode(node, customUI, this));
}
// Add the edges now
var drawableEdges = new List<DrawableEdge<NodeAnchor>>();
foreach (var drawableMaterialNode in m_DrawableNodes)
{
var baseNode = drawableMaterialNode.m_Node;
foreach (var slot in baseNode.GetOutputSlots<ISlot>())
{
var sourceAnchor = (NodeAnchor)drawableMaterialNode.Children().FirstOrDefault(x => x is NodeAnchor && ((NodeAnchor)x).m_Slot == slot);
var edges = baseNode.owner.GetEdges(new SlotReference(baseNode.guid, slot.id));
foreach (var edge in edges)
{
var toNode = baseNode.owner.GetNodeFromGuid(edge.inputSlot.nodeGuid);
var toSlot = toNode.FindInputSlot<ISlot>(edge.inputSlot.slotId);
var targetNode = m_DrawableNodes.FirstOrDefault(x => x.m_Node == toNode);
var targetAnchor = (NodeAnchor)targetNode.Children().FirstOrDefault(x => x is NodeAnchor && ((NodeAnchor)x).m_Slot == toSlot);
drawableEdges.Add(new DrawableEdge<NodeAnchor>(edge, this, sourceAnchor, targetAnchor));
}
}
}
// Add proxy inputs for when edges are not connect
var nullInputSlots = new List<NullInputProxy>();
foreach (var drawableMaterialNode in m_DrawableNodes)
{
var baseNode = drawableMaterialNode.m_Node;
// grab the input slots where there are no edges
foreach (var slot in baseNode.GetInputsWithNoConnection())
{
// if there is no anchor, continue
// this can happen if we are in collapsed mode
var sourceAnchor = (NodeAnchor)drawableMaterialNode.Children().FirstOrDefault(x => x is NodeAnchor && ((NodeAnchor)x).m_Slot == slot);
if (sourceAnchor == null)
continue;
nullInputSlots.Add(new NullInputProxy(baseNode, slot, sourceAnchor));
}
}
var toReturn = new List<CanvasElement>();
toReturn.AddRange(m_DrawableNodes.Select(x => (CanvasElement)x));
toReturn.AddRange(drawableEdges.Select(x => (CanvasElement)x));
toReturn.AddRange(nullInputSlots.Select(x => (CanvasElement)x));
//toReturn.Add(new FloatingPreview(new Rect(Screen.width - 300, Screen.height - 300, 300, 300), pixelGraph.nodes.FirstOrDefault(x => x is PixelShaderNode)));
Debug.LogFormat("Returning {0} nodes", m_DrawableNodes.Count);
Debug.LogFormat("Returning {0} drawableEdges", drawableEdges.Count);
Debug.LogFormat("Returning {0} nullInputSlots", nullInputSlots.Count);
return toReturn.ToArray();
}
public void DeleteElement(CanvasElement e)
{
// do nothing here, we want to use delete elements.
// delete elements ensures that edges are deleted before nodes.
}
public void DeleteElements(List<CanvasElement> elements)
{
var graph = graphAsset.graph;
var toRemoveEdge = new List<IEdge>();
// delete selected edges first
foreach (var e in elements.OfType<Edge<NodeAnchor>>())
{
//find the edge
var edge = graph.edges.FirstOrDefault(x => graph.GetNodeFromGuid(x.outputSlot.nodeGuid).FindOutputSlot<ISlot>(x.outputSlot.slotId) == e.Left.m_Slot
&& graph.GetNodeFromGuid(x.inputSlot.nodeGuid).FindInputSlot<ISlot>(x.inputSlot.slotId) == e.Right.m_Slot);
toRemoveEdge.Add(edge);
}
var toRemoveNode = new List<INode>();
// now delete the nodes
foreach (var e in elements.OfType<DrawableNode>())
{
if (!e.m_Node.canDeleteNode)
continue;
toRemoveNode.Add(e.m_Node);
}
graph.RemoveElements(toRemoveNode, toRemoveEdge);
MarkDirty();
}
public void Connect(NodeAnchor a, NodeAnchor b)
{
var graph = graphAsset.graph;
graph.Connect(a.m_Node.GetSlotReference(a.m_Slot.id), b.m_Node.GetSlotReference(b.m_Slot.id));
MarkDirty();
}
public void Addnode(INode node)
{
var graph = graphAsset.graph;
graph.AddNode(node);
MarkDirty();
}
public void MarkDirty()
{
EditorUtility.SetDirty(graphAsset.GetScriptableObject());
}
/*
}
public class FloatingPreview : CanvasElement
{
private AbstractMaterialNode m_Node;
public FloatingPreview(Rect position, AbstractMaterialNode node)
{
m_Node = node as AbstractMaterialNode;
m_Translation = new Vector2(position.x, position.y);
m_Scale = new Vector3(position.width, position.height, 1);
m_Caps |= Capabilities.Floating | Capabilities.Unselectable;
}
public override void Render(Rect parentRect, Canvas2D canvas)
{
var drawArea = new Rect(0, 0, scale.x, scale.y);
Color backgroundColor = new Color(0.0f, 0.0f, 0.0f, 0.7f);
EditorGUI.DrawRect(drawArea, backgroundColor);
drawArea.width -= 10;
drawArea.height -= 10;
drawArea.x += 5;
drawArea.y += 5;
GL.sRGBWrite = (QualitySettings.activeColorSpace == ColorSpace.Linear);
GUI.DrawTexture(drawArea, m_Node.RenderPreview(new Rect(0, 0, drawArea.width, drawArea.height)), ScaleMode.StretchToFill, false);
GL.sRGBWrite = false;
Invalidate();
canvas.Repaint();
}*
}*/
}