【a】XNode

This commit is contained in:
mzh
2026-01-06 14:42:02 +08:00
parent 2e8accfed8
commit 273200202d
97 changed files with 6654 additions and 0 deletions

View File

@@ -0,0 +1,71 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using XNode;
using XNodeEditor;
namespace XNodeEditor {
[CustomPropertyDrawer(typeof(NodeEnumAttribute))]
public class NodeEnumDrawer : PropertyDrawer {
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
EditorGUI.BeginProperty(position, label, property);
EnumPopup(position, property, label);
EditorGUI.EndProperty();
}
public static void EnumPopup(Rect position, SerializedProperty property, GUIContent label) {
// Throw error on wrong type
if (property.propertyType != SerializedPropertyType.Enum) {
throw new ArgumentException("Parameter selected must be of type System.Enum");
}
// Add label
position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label);
// Get current enum name
string enumName = "";
if (property.enumValueIndex >= 0 && property.enumValueIndex < property.enumDisplayNames.Length) enumName = property.enumDisplayNames[property.enumValueIndex];
#if UNITY_2017_1_OR_NEWER
// Display dropdown
if (EditorGUI.DropdownButton(position, new GUIContent(enumName), FocusType.Passive)) {
// Position is all wrong if we show the dropdown during the node draw phase.
// Instead, add it to onLateGUI to display it later.
NodeEditorWindow.current.onLateGUI += () => ShowContextMenuAtMouse(property);
}
#else
// Display dropdown
if (GUI.Button(position, new GUIContent(enumName), "MiniPopup")) {
// Position is all wrong if we show the dropdown during the node draw phase.
// Instead, add it to onLateGUI to display it later.
NodeEditorWindow.current.onLateGUI += () => ShowContextMenuAtMouse(property);
}
#endif
}
public static void ShowContextMenuAtMouse(SerializedProperty property) {
// Initialize menu
GenericMenu menu = new GenericMenu();
// Add all enum display names to menu
for (int i = 0; i < property.enumDisplayNames.Length; i++) {
int index = i;
menu.AddItem(new GUIContent(property.enumDisplayNames[i]), false, () => SetEnum(property, index));
}
// Display at cursor position
Rect r = new Rect(Event.current.mousePosition, new Vector2(0, 0));
menu.DropDown(r);
}
private static void SetEnum(SerializedProperty property, int index) {
property.enumValueIndex = index;
property.serializedObject.ApplyModifiedProperties();
property.serializedObject.Update();
}
}
}

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 83db81f92abadca439507e25d517cabe
timeCreated: 1541633798
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 327994a52f523b641898a39ff7500a02
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,48 @@
#if UNITY_EDITOR && ODIN_INSPECTOR
using System;
using System.Collections.Generic;
using System.Reflection;
using Sirenix.OdinInspector.Editor;
using UnityEngine;
using XNode;
namespace XNodeEditor {
internal class OdinNodeInGraphAttributeProcessor<T> : OdinAttributeProcessor<T> where T : Node {
public override bool CanProcessSelfAttributes(InspectorProperty property) {
return false;
}
public override bool CanProcessChildMemberAttributes(InspectorProperty parentProperty, MemberInfo member) {
if (!NodeEditor.inNodeEditor)
return false;
if (member.MemberType == MemberTypes.Field) {
switch (member.Name) {
case "graph":
case "position":
case "ports":
return true;
default:
break;
}
}
return false;
}
public override void ProcessChildMemberAttributes(InspectorProperty parentProperty, MemberInfo member, List<Attribute> attributes) {
switch (member.Name) {
case "graph":
case "position":
case "ports":
attributes.Add(new HideInInspector());
break;
default:
break;
}
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3cf2561fbfea9a041ac81efbbb5b3e0d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,49 @@
#if UNITY_EDITOR && ODIN_INSPECTOR
using Sirenix.OdinInspector;
using Sirenix.OdinInspector.Editor;
using Sirenix.Utilities.Editor;
using UnityEngine;
using XNode;
namespace XNodeEditor {
public class InputAttributeDrawer : OdinAttributeDrawer<XNode.Node.InputAttribute> {
protected override bool CanDrawAttributeProperty(InspectorProperty property) {
Node node = property.Tree.WeakTargets[0] as Node;
return node != null;
}
protected override void DrawPropertyLayout(GUIContent label) {
Node node = Property.Tree.WeakTargets[0] as Node;
NodePort port = node.GetInputPort(Property.Name);
if (!NodeEditor.inNodeEditor) {
if (Attribute.backingValue == XNode.Node.ShowBackingValue.Always || Attribute.backingValue == XNode.Node.ShowBackingValue.Unconnected && !port.IsConnected)
CallNextDrawer(label);
return;
}
if (Property.Tree.WeakTargets.Count > 1) {
SirenixEditorGUI.WarningMessageBox("Cannot draw ports with multiple nodes selected");
return;
}
if (port != null) {
var portPropoerty = Property.Tree.GetUnityPropertyForPath(Property.UnityPropertyPath);
if (portPropoerty == null) {
SirenixEditorGUI.ErrorMessageBox("Port property missing at: " + Property.UnityPropertyPath);
return;
} else {
var labelWidth = Property.GetAttribute<LabelWidthAttribute>();
if (labelWidth != null)
GUIHelper.PushLabelWidth(labelWidth.Width);
NodeEditorGUILayout.PropertyField(portPropoerty, label == null ? GUIContent.none : label, true, GUILayout.MinWidth(30));
if (labelWidth != null)
GUIHelper.PopLabelWidth();
}
}
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2fd590b2e9ea0bd49b6986a2ca9010ab
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,49 @@
#if UNITY_EDITOR && ODIN_INSPECTOR
using Sirenix.OdinInspector;
using Sirenix.OdinInspector.Editor;
using Sirenix.Utilities.Editor;
using UnityEngine;
using XNode;
namespace XNodeEditor {
public class OutputAttributeDrawer : OdinAttributeDrawer<XNode.Node.OutputAttribute> {
protected override bool CanDrawAttributeProperty(InspectorProperty property) {
Node node = property.Tree.WeakTargets[0] as Node;
return node != null;
}
protected override void DrawPropertyLayout(GUIContent label) {
Node node = Property.Tree.WeakTargets[0] as Node;
NodePort port = node.GetOutputPort(Property.Name);
if (!NodeEditor.inNodeEditor) {
if (Attribute.backingValue == XNode.Node.ShowBackingValue.Always || Attribute.backingValue == XNode.Node.ShowBackingValue.Unconnected && !port.IsConnected)
CallNextDrawer(label);
return;
}
if (Property.Tree.WeakTargets.Count > 1) {
SirenixEditorGUI.WarningMessageBox("Cannot draw ports with multiple nodes selected");
return;
}
if (port != null) {
var portPropoerty = Property.Tree.GetUnityPropertyForPath(Property.UnityPropertyPath);
if (portPropoerty == null) {
SirenixEditorGUI.ErrorMessageBox("Port property missing at: " + Property.UnityPropertyPath);
return;
} else {
var labelWidth = Property.GetAttribute<LabelWidthAttribute>();
if (labelWidth != null)
GUIHelper.PushLabelWidth(labelWidth.Width);
NodeEditorGUILayout.PropertyField(portPropoerty, label == null ? GUIContent.none : label, true, GUILayout.MinWidth(30));
if (labelWidth != null)
GUIHelper.PopLabelWidth();
}
}
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e7ebd8f2b42e2384aa109551dc46af88
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: