First commit

This commit is contained in:
Misaki
2024-11-02 17:58:52 +09:00
commit e645a5327b
153 changed files with 3729 additions and 0 deletions

8
Sample/Editor.meta Normal file
View File

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

View File

@@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Codice.CM.Common;
using Misaki.GraphView.Editor;
namespace Misaki.GraphView.Sample.Editor
{
public class ExposedPropertyTypeManager : IExposedPropertyTypeManager
{
private readonly Dictionary<Type, Type> _propertyTypes = new();
public void AddPropertyType<T, TV>() where T : ExposedProperty
{
_propertyTypes.Add(typeof(T), typeof(TV));
}
public void AddPropertyType(Type type, Type valueType)
{
if (type.IsSubclassOf(typeof(ExposedProperty)))
{
_propertyTypes.Add(type, valueType);
}
}
public void RemovePropertyType<T>()
{
_propertyTypes.Remove(typeof(T));
}
public void RemovePropertyType(Type type)
{
_propertyTypes.Remove(type);
}
public ReadOnlyDictionary<Type, Type> GetPropertyTypes()
{
//_propertyTypes.AsReadOnly(); // Ancient .NET version doesn't have this method :(
return new ReadOnlyDictionary<Type, Type>(_propertyTypes);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 82e447a37b3c4c06acde96775d3b7935
timeCreated: 1730458201

View File

@@ -0,0 +1,33 @@
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEngine;
namespace Misaki.GraphView.Sample.Editor
{
[CustomEditor(typeof(SampleGraphAsset))]
public class SampleGraphAssetEditor : UnityEditor.Editor
{
[OnOpenAsset]
public static bool OnOpenAsset(int instanceID, int line)
{
var asset = EditorUtility.InstanceIDToObject(instanceID) as SampleGraphAsset;
if (asset != null)
{
SampleGraphEditor.Open(asset);
return true;
}
return false;
}
public override void OnInspectorGUI()
{
if (GUILayout.Button("Execute"))
{
var asset = target as SampleGraphAsset;
asset?.Execute();
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 9d328a580873455bbc885370d71260fb
timeCreated: 1730134525

View File

@@ -0,0 +1,18 @@
{
"name": "GraphView.Sample.Editor",
"rootNamespace": "Misaki.GraphView.Sample.Editor",
"references": [
"GUID:f9745e3c5d586134288023f609b080e2",
"GUID:533d7c0252a224f4b91c72a79c31c026",
"GUID:ccfdc692d87db8b49b9ec88c2ec0ab79"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 3f931024d736a2d44a1ecb45293a4c31
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using Misaki.GraphView.Editor;
using UnityEngine;
namespace Misaki.GraphView.Sample.Editor
{
public class PortColorManager : IPortColorManager
{
private readonly Dictionary<Type, Color> _colors = new();
public void SetColor<T>(Color color)
{
_colors[typeof(T)] = color;
}
public bool TryGetColor(Type valueType, out Color color)
{
return _colors.TryGetValue(valueType, out color);
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 54afba377e1b7be4a902a175a3255c55

View File

@@ -0,0 +1,140 @@
using Misaki.GraphView;
using Misaki.GraphView.Editor;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
namespace Misaki.GraphView.Sample.Editor
{
public class SampleGraphEditor : EditorWindow
{
[SerializeField]
private StyleSheet _styleSheet;
private readonly PortColorManager _portColorManager = new ();
private readonly ExposedPropertyTypeManager _exposedPropertyTypeManager = new ();
private GraphObject _currentAsset;
private GraphViewConfig _config;
[MenuItem("Tools/SampleGraphEditor")]
private static void Open()
{
var window = CreateWindow<SampleGraphEditor>(typeof(SceneView));
window.titleContent = new GUIContent("Sample Graph Editor");
}
public static void Open(GraphObject asset)
{
var window = GetWindow<SampleGraphEditor>(typeof(SceneView));
window.Clear();
window.LoadAsset(asset);
window.titleContent = new GUIContent(asset.name);
window.DrawGraph();
window.Focus();
}
public SampleGraphEditor()
{
_portColorManager.SetColor<uint>(Color.cyan);
_exposedPropertyTypeManager.AddPropertyType<FloatProperty, float>();
}
private void Clear()
{
rootVisualElement.Clear();
}
private void LoadAsset(GraphObject asset)
{
Clear();
_currentAsset = asset;
_config = new()
{
direction = GraphDirection.Horizontal,
miniMapConfig = new ()
{
enable = false,
},
zoomConfig = new ()
{
minScale = 0.25f,
maxScale = 2f,
scaleStep = 0.1f
},
graphObject = _currentAsset,
serializedObject = new SerializedObject(_currentAsset),
portColorManager = _portColorManager,
exposedPropertyTypeManager = _exposedPropertyTypeManager
};
}
private void OnEnable()
{
if (_currentAsset == null)
{
var label = new Label("No asset loaded")
{
style =
{
flexGrow = 1,
unityTextAlign = TextAnchor.MiddleCenter,
fontSize = 20
}
};
rootVisualElement.Add(label);
}
else
{
LoadAsset(_currentAsset);
DrawGraph();
}
}
private void DrawGraph()
{
var graphContainer = new VisualElement
{
name = "GraphContainer",
style =
{
flexDirection = FlexDirection.Column
}
};
graphContainer.StretchToParentSize();
var graphView = new GraphView.Editor.GraphView(this, _config);
graphView.styleSheets.Add(_styleSheet);
graphView.UpdateViewTransform(_currentAsset.graphPosition, _currentAsset.graphScale);
var toolbar = new GraphToolbarView(_currentAsset);
toolbar.BlackboardButtonClicked += graphView.ToggleBlackboardViewVisibility;
toolbar.InspectButtonClicked += graphView.ToggleInspectorViewVisibility;
// We can not directly add the graph view to the graphContainer since the RectangleSelector is calculated base on the parent position, so we need to add it to a container first
var graphViewContainer = new VisualElement
{
name = "GraphViewContainer",
style =
{
flexGrow = 1
}
};
graphContainer.Add(toolbar);
graphViewContainer.Add(graphView);
graphContainer.Add(graphViewContainer);
rootVisualElement.Add(graphContainer);
// // If no asset is loaded, show a warning label
// if (currentAsset == null)
// {
// RenderNoAssetAlert();
// }
}
}
}

View File

@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: aa9791125630bcc4fb4153e625061b57
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences:
- m_ViewDataDictionary: {instanceID: 0}
- _styleSheet: {fileID: 7433441132597879392, guid: ad06b58f16bdc1c429c7a82e0552c636,
type: 3}
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

165
Sample/GraphAsset.asset Normal file
View File

@@ -0,0 +1,165 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: a6ff09617d9e7ad4db1c77355ecb6ee1, type: 3}
m_Name: GraphAsset
m_EditorClassIdentifier:
_nodes:
- rid: 299037523270959196
- rid: 299037523270959197
- rid: 299037523270959199
_connections:
- _inputSlotData:
slotName: a
nodeID: b055be5b-5e72-4715-8981-d38913599762
slotIndex: 0
direction: 0
valueType: System.Single
_outputSlotData:
slotName: value
nodeID: 7a3d7992-0465-458a-bbd8-e972d77b1e34
slotIndex: 0
direction: 1
valueType: System.Object
- _inputSlotData:
slotName: _input
nodeID: e630425e-5b42-4839-9e4a-9b134c1e497c
slotIndex: 0
direction: 0
valueType: System.Single
_outputSlotData:
slotName: _result
nodeID: b055be5b-5e72-4715-8981-d38913599762
slotIndex: 0
direction: 1
valueType: System.Single
_exposedProperties:
- rid: 299037523270959195
graphPosition: {x: -119.333336, y: -80.666664, z: 0}
graphScale: {x: 1.331, y: 1.331, z: 1}
references:
version: 2
RefIds:
- rid: 299037523270959195
type: {class: FloatProperty, ns: Misaki.GraphView.Sample, asm: GraphView.Sample}
data:
id: facf43a4-c260-4e6a-a767-85cdbe63505e
propertyName: Float Field
propertyType: Misaki.GraphView.Sample.FloatProperty
value: 1
- rid: 299037523270959196
type: {class: PropertyInputNode, ns: Misaki.GraphView, asm: GraphView}
data:
_inputs: []
_outputs:
- _linkedSlotData:
- slotName: a
nodeID: b055be5b-5e72-4715-8981-d38913599762
slotIndex: 0
direction: 0
valueType: System.Single
owner:
rid: 299037523270959196
slotData:
slotName: value
nodeID: 7a3d7992-0465-458a-bbd8-e972d77b1e34
slotIndex: 0
direction: 1
valueType: System.Object
_graphObject: {fileID: 11400000}
_id: 7a3d7992-0465-458a-bbd8-e972d77b1e34
position:
serializedVersion: 2
x: 328.66666
y: 503.99997
width: 98.66666
height: 36
_property:
rid: 299037523270959195
- rid: 299037523270959197
type: {class: OutputNode, ns: Misaki.GraphView.Sample, asm: GraphView.Sample}
data:
_inputs:
- _linkedSlotData:
- slotName: _result
nodeID: b055be5b-5e72-4715-8981-d38913599762
slotIndex: 0
direction: 1
valueType: System.Single
owner:
rid: 299037523270959197
slotData:
slotName: _input
nodeID: e630425e-5b42-4839-9e4a-9b134c1e497c
slotIndex: 0
direction: 0
valueType: System.Single
_outputs: []
_graphObject: {fileID: 11400000}
_id: e630425e-5b42-4839-9e4a-9b134c1e497c
position:
serializedVersion: 2
x: 699.3334
y: 437.3333
width: 124.666626
height: 78.66666
- rid: 299037523270959199
type: {class: AddNode, ns: Misaki.GraphView.Sample, asm: GraphView.Sample}
data:
_inputs:
- _linkedSlotData:
- slotName: value
nodeID: 7a3d7992-0465-458a-bbd8-e972d77b1e34
slotIndex: 0
direction: 1
valueType: System.Object
owner:
rid: 299037523270959199
slotData:
slotName: a
nodeID: b055be5b-5e72-4715-8981-d38913599762
slotIndex: 0
direction: 0
valueType: System.Single
- _linkedSlotData: []
owner:
rid: 299037523270959199
slotData:
slotName: b
nodeID: b055be5b-5e72-4715-8981-d38913599762
slotIndex: 1
direction: 0
valueType: System.Single
_outputs:
- _linkedSlotData:
- slotName: _input
nodeID: e630425e-5b42-4839-9e4a-9b134c1e497c
slotIndex: 0
direction: 0
valueType: System.Single
owner:
rid: 299037523270959199
slotData:
slotName: _result
nodeID: b055be5b-5e72-4715-8981-d38913599762
slotIndex: 0
direction: 1
valueType: System.Single
_graphObject: {fileID: 11400000}
_id: b055be5b-5e72-4715-8981-d38913599762
position:
serializedVersion: 2
x: 507.88882
y: 437.76617
width: 0
height: 0
a: 0
b: 1

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2b1c2c68ad45b624db14c679beccf607
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

3
Sample/Runtime.meta Normal file
View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 2b0a56422e82402498424519cbeae359
timeCreated: 1730133673

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 123b16431f374c7ab3b89c37866a9ea9
timeCreated: 1730458328

View File

@@ -0,0 +1,18 @@
using System;
namespace Misaki.GraphView.Sample
{
[Serializable]
public class FloatProperty : ExposedProperty
{
public float value;
public override object Value
{
get => value;
set => this.value = (float) value;
}
public override Type GetValueType() => typeof(float);
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: bdcf54264961455791242e8bbc7400c1
timeCreated: 1730458344

View File

@@ -0,0 +1,17 @@
{
"name": "GraphView.Sample",
"rootNamespace": "Misaki.GraphView.Sample",
"references": [
"GUID:f9745e3c5d586134288023f609b080e2",
"GUID:533d7c0252a224f4b91c72a79c31c026"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: ccfdc692d87db8b49b9ec88c2ec0ab79
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -0,0 +1,30 @@
#if UNITY_EDITOR
using Misaki.GraphView.Editor;
#endif
namespace Misaki.GraphView.Sample
{
[NodeInfo("Add", "Math")]
public class AddNode : BackTraceBaseNode
{
[NodeInput]
#if UNITY_EDITOR
[InspectorInput]
#endif
public float a;
[NodeInput]
#if UNITY_EDITOR
[InspectorInput]
#endif
public float b;
[NodeOutput]
private float _result;
protected override void OnExecute()
{
_result = a + b;
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: fe1c51aa37dba09468a65f5594146083

View File

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

View File

@@ -0,0 +1,16 @@
namespace Misaki.GraphView.Sample
{
public abstract class BackTraceBaseNode : BaseNode
{
protected override void OnPullData(Slot input)
{
if (input.LinkedSlotData.Count == 0)
{
return;
}
var outputNode = GraphObject.GetNode(input.LinkedSlotData[0].nodeID);
outputNode.Execute();
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: a761276bd0f3a4a4cb4b0894d193f4cd

View File

@@ -0,0 +1,16 @@
using UnityEngine;
namespace Misaki.GraphView.Sample
{
[NodeInfo("Output Node", "Output")]
public class OutputNode : BackTraceBaseNode
{
[NodeInput]
private float _input;
protected override void OnExecute()
{
Debug.Log(_input);
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 42ed2641b4fc11240be0abda76236178

View File

@@ -0,0 +1,21 @@
using UnityEngine;
namespace Misaki.GraphView.Sample
{
[CreateAssetMenu(fileName = "GraphAsset", menuName = "Scriptable Objects/GraphAsset")]
public class SampleGraphAsset : GraphObject
{
public override void Execute()
{
Nodes.ClearAllExecuteFlag();
foreach (var node in Nodes)
{
if (node is OutputNode outputNode)
{
outputNode.Execute();
}
}
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: a6ff09617d9e7ad4db1c77355ecb6ee1

8
Sample/Styles.meta Normal file
View File

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

22
Sample/Styles/Style.uss Normal file
View File

@@ -0,0 +1,22 @@
GridBackground
{
--grid-background-color : rgb(32, 32, 32);
--line-color : rgba(193, 196, 192, 0.1);
--thick-line-color : rgba(193, 196, 192, 0.2);
--spacing : 15;
}
.graphElement.node.math VisualElement#title
{
background-color : rgba(64, 96, 128, 0.8);
}
.graphElement.node.input VisualElement#title
{
background-color : rgba(128, 64, 64, 0.8);
}
.graphElement.node.output VisualElement#title
{
background-color : rgba(64, 128, 70, 0.8);
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ad06b58f16bdc1c429c7a82e0552c636
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0}
disableValidation: 0