From 0fd19497b08d00886d999483ee1f6f82765b89a1 Mon Sep 17 00:00:00 2001 From: taoria <445625470@qq.com> Date: Fri, 15 Jul 2022 17:27:20 +0800 Subject: [PATCH] feat: force blackboard select no scene object --- Resources.meta | 8 + ...Newtonsoft.Json-for-Unity.Converters.asset | 162 +++++++++++++++++ ...nsoft.Json-for-Unity.Converters.asset.meta | 8 + Sample/TestExposedReference.cs | 10 ++ Sample/TestExposedReference.cs.meta | 3 + TNode/DataWrapper.cs | 2 + TNode/Editor/Serialization/NodeDataWrapper.cs | 2 +- TNode/Models/SceneObjectWrapper.cs | 167 +++++++++++++++++- TNode/Runtime/SceneSerializedData.cs | 9 + TNode/Runtime/SceneSerializedData.cs.meta | 3 + TNode/RuntimeCache/RuntimeCache.cs | 41 +++-- .../DefaultGraphBlackboardView.cs | 5 +- .../GraphBlackboardPropertyField.cs | 21 +++ .../GraphBlackboardPropertyField.cs.meta | 3 + TextMesh Pro.meta | 8 + 15 files changed, 430 insertions(+), 22 deletions(-) create mode 100644 Resources.meta create mode 100644 Resources/Newtonsoft.Json-for-Unity.Converters.asset create mode 100644 Resources/Newtonsoft.Json-for-Unity.Converters.asset.meta create mode 100644 Sample/TestExposedReference.cs create mode 100644 Sample/TestExposedReference.cs.meta create mode 100644 TNode/Runtime/SceneSerializedData.cs create mode 100644 TNode/Runtime/SceneSerializedData.cs.meta create mode 100644 TNodeGraphViewImpl/Editor/GraphBlackboard/GraphBlackboardPropertyField.cs create mode 100644 TNodeGraphViewImpl/Editor/GraphBlackboard/GraphBlackboardPropertyField.cs.meta create mode 100644 TextMesh Pro.meta diff --git a/Resources.meta b/Resources.meta new file mode 100644 index 0000000..d428cde --- /dev/null +++ b/Resources.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 630fb8569cca3804a80f2fb55f7890f2 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Resources/Newtonsoft.Json-for-Unity.Converters.asset b/Resources/Newtonsoft.Json-for-Unity.Converters.asset new file mode 100644 index 0000000..b01ce28 --- /dev/null +++ b/Resources/Newtonsoft.Json-for-Unity.Converters.asset @@ -0,0 +1,162 @@ +%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: ce56e4dbb13e1644aa983b6dd170e4a7, type: 3} + m_Name: Newtonsoft.Json-for-Unity.Converters + m_EditorClassIdentifier: + useUnityContractResolver: 1 + useAllOutsideConverters: 0 + outsideConverters: + - enabled: 0 + converterName: TNode.JsonSerialize.NodeDataConverter + settings: [] + - enabled: 0 + converterName: TNode.JsonSerialize.UnityObjectConverter + settings: [] + - enabled: 0 + converterName: TNode.JsonSerialize.Vector3Converter + settings: [] + useAllUnityConverters: 1 + unityConverters: + - enabled: 1 + converterName: Newtonsoft.Json.UnityConverters.AI.NavMesh.NavMeshQueryFilterConverter + settings: [] + - enabled: 1 + converterName: Newtonsoft.Json.UnityConverters.AI.NavMesh.NavMeshTriangulationConverter + settings: [] + - enabled: 1 + converterName: Newtonsoft.Json.UnityConverters.Camera.CullingGroupEventConverter + settings: [] + - enabled: 1 + converterName: Newtonsoft.Json.UnityConverters.Geometry.BoundsConverter + settings: [] + - enabled: 1 + converterName: Newtonsoft.Json.UnityConverters.Geometry.BoundsIntConverter + settings: [] + - enabled: 1 + converterName: Newtonsoft.Json.UnityConverters.Geometry.PlaneConverter + settings: [] + - enabled: 1 + converterName: Newtonsoft.Json.UnityConverters.Geometry.RectConverter + settings: [] + - enabled: 1 + converterName: Newtonsoft.Json.UnityConverters.Geometry.RectIntConverter + settings: [] + - enabled: 1 + converterName: Newtonsoft.Json.UnityConverters.Geometry.RectOffsetConverter + settings: [] + - enabled: 1 + converterName: Newtonsoft.Json.UnityConverters.Hashing.Hash128Converter + settings: [] + - enabled: 1 + converterName: Newtonsoft.Json.UnityConverters.Math.Color32Converter + settings: [] + - enabled: 1 + converterName: Newtonsoft.Json.UnityConverters.Math.ColorConverter + settings: [] + - enabled: 1 + converterName: Newtonsoft.Json.UnityConverters.Math.Matrix4x4Converter + settings: [] + - enabled: 1 + converterName: Newtonsoft.Json.UnityConverters.Math.QuaternionConverter + settings: [] + - enabled: 1 + converterName: Newtonsoft.Json.UnityConverters.Math.SphericalHarmonicsL2Converter + settings: [] + - enabled: 1 + converterName: Newtonsoft.Json.UnityConverters.Math.Vector2Converter + settings: [] + - enabled: 1 + converterName: Newtonsoft.Json.UnityConverters.Math.Vector2IntConverter + settings: [] + - enabled: 1 + converterName: Newtonsoft.Json.UnityConverters.Math.Vector3Converter + settings: [] + - enabled: 1 + converterName: Newtonsoft.Json.UnityConverters.Math.Vector3IntConverter + settings: [] + - enabled: 1 + converterName: Newtonsoft.Json.UnityConverters.Math.Vector4Converter + settings: [] + - enabled: 1 + converterName: Newtonsoft.Json.UnityConverters.NativeArray.NativeArrayConverter + settings: [] + - enabled: 1 + converterName: Newtonsoft.Json.UnityConverters.Physics.JointDriveConverter + settings: [] + - enabled: 1 + converterName: Newtonsoft.Json.UnityConverters.Physics.JointLimitsConverter + settings: [] + - enabled: 1 + converterName: Newtonsoft.Json.UnityConverters.Physics.SoftJointLimitConverter + settings: [] + - enabled: 1 + converterName: Newtonsoft.Json.UnityConverters.Physics2D.ColliderDistance2DConverter + settings: [] + - enabled: 1 + converterName: Newtonsoft.Json.UnityConverters.Physics2D.ContactFilter2DConverter + settings: [] + - enabled: 1 + converterName: Newtonsoft.Json.UnityConverters.Random.RandomStateConverter + settings: [] + - enabled: 1 + converterName: Newtonsoft.Json.UnityConverters.Scripting.LayerMaskConverter + settings: [] + - enabled: 1 + converterName: Newtonsoft.Json.UnityConverters.Scripting.RangeIntConverter + settings: [] + useAllJsonNetConverters: 1 + jsonNetConverters: + - enabled: 1 + converterName: Newtonsoft.Json.Converters.StringEnumConverter + settings: [] + - enabled: 1 + converterName: Newtonsoft.Json.Converters.VersionConverter + settings: [] + - enabled: 0 + converterName: Newtonsoft.Json.Converters.BinaryConverter + settings: [] + - enabled: 0 + converterName: Newtonsoft.Json.Converters.BsonObjectIdConverter + settings: [] + - enabled: 0 + converterName: Newtonsoft.Json.Converters.DataSetConverter + settings: [] + - enabled: 0 + converterName: Newtonsoft.Json.Converters.DataTableConverter + settings: [] + - enabled: 0 + converterName: Newtonsoft.Json.Converters.DiscriminatedUnionConverter + settings: [] + - enabled: 0 + converterName: Newtonsoft.Json.Converters.EntityKeyMemberConverter + settings: [] + - enabled: 0 + converterName: Newtonsoft.Json.Converters.ExpandoObjectConverter + settings: [] + - enabled: 0 + converterName: Newtonsoft.Json.Converters.IsoDateTimeConverter + settings: [] + - enabled: 0 + converterName: Newtonsoft.Json.Converters.JavaScriptDateTimeConverter + settings: [] + - enabled: 0 + converterName: Newtonsoft.Json.Converters.KeyValuePairConverter + settings: [] + - enabled: 0 + converterName: Newtonsoft.Json.Converters.RegexConverter + settings: [] + - enabled: 0 + converterName: Newtonsoft.Json.Converters.UnixDateTimeConverter + settings: [] + - enabled: 0 + converterName: Newtonsoft.Json.Converters.XmlNodeConverter + settings: [] diff --git a/Resources/Newtonsoft.Json-for-Unity.Converters.asset.meta b/Resources/Newtonsoft.Json-for-Unity.Converters.asset.meta new file mode 100644 index 0000000..ec4e066 --- /dev/null +++ b/Resources/Newtonsoft.Json-for-Unity.Converters.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 466d3febdbd656c4f9728b1116b1564f +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Sample/TestExposedReference.cs b/Sample/TestExposedReference.cs new file mode 100644 index 0000000..a44add9 --- /dev/null +++ b/Sample/TestExposedReference.cs @@ -0,0 +1,10 @@ +using UnityEngine; + +namespace Sample{ + // Create at Asset/Test + [CreateAssetMenu(fileName = "NewData", menuName = "Test/Data", order = 1)] + public class TestExposedReference:ScriptableObject{ + public ExposedReference camera; + public ExposedReference go; + } +} \ No newline at end of file diff --git a/Sample/TestExposedReference.cs.meta b/Sample/TestExposedReference.cs.meta new file mode 100644 index 0000000..f6c4b0e --- /dev/null +++ b/Sample/TestExposedReference.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: fed858872d394fb8896d48178f8a7d78 +timeCreated: 1657862979 \ No newline at end of file diff --git a/TNode/DataWrapper.cs b/TNode/DataWrapper.cs index 9aec6b7..95b3afd 100644 --- a/TNode/DataWrapper.cs +++ b/TNode/DataWrapper.cs @@ -21,6 +21,8 @@ namespace TNode.Editor.Serialization{ Cache.Add(data,wrapper); return wrapper; } + + public event Action> OnValueChanged; public void SetValue(string path, object value){ diff --git a/TNode/Editor/Serialization/NodeDataWrapper.cs b/TNode/Editor/Serialization/NodeDataWrapper.cs index cff0ea0..816df2e 100644 --- a/TNode/Editor/Serialization/NodeDataWrapper.cs +++ b/TNode/Editor/Serialization/NodeDataWrapper.cs @@ -60,7 +60,7 @@ namespace TNode.Editor.Serialization{ // private static readonly Dictionary Cache = new (); // public event Action OnValueChanged; // /// - // /// Create a new wrapper or get a cached wrapper for the given data + // /// Create a new wrapper or get a infoCached wrapper for the given data // /// // /// node data,an implemented type is acceptable // /// diff --git a/TNode/Models/SceneObjectWrapper.cs b/TNode/Models/SceneObjectWrapper.cs index cc75204..169099c 100644 --- a/TNode/Models/SceneObjectWrapper.cs +++ b/TNode/Models/SceneObjectWrapper.cs @@ -1,7 +1,11 @@ -using System.Collections.Generic; -using System.Linq; +using System; +using System.Collections.Generic; using TNode.Editor.Serialization; +using TNode.RuntimeCache; using UnityEngine; +using UnityEngine.SceneManagement; +using UnityEngine.Serialization; +using Object = UnityEngine.Object; namespace TNode.Models{ @@ -9,23 +13,170 @@ namespace TNode.Models{ /// Scene Object wrapper use to serialize blackboard data /// public class SceneObjectWrapper:DataWrapper{ - public bool loadedFromScene =false; + public bool loadedFromScene = false; + [NonSerialized] + public List PossibleSceneFields; + public List SceneFields; + public struct SceneSerializationEntry{ + public string ScenePath; + public string FieldName; + public string SceneObject; - public List sceneObjects = new List(); - public void LoadFromScene(){ - } + public bool infoCached; + //Reflection may be expensive, so we cache the type + + public Type Type; + //we need to cache blackboard data info + public void LoadBlackboardInfo(){ + if (infoCached) return; + infoCached = true; + Type = data.GetType(); + PossibleSceneFields = new List(); + foreach (var field in Type.GetFields()){ + if (field.FieldType == typeof(Object)){ + PossibleSceneFields.Add(field.Name); + } + } + } + #region Oboselete Region for serialization + + // + // public string BuildThroughTransform(Object go, Transform root,int id){ + // if (root.gameObject == go) return $"/{id}"; + // var res = root.transform.Find(go.name); + // if (res != null){ + // for (int j = 0; j < root.transform.childCount; j++){ + // var child = root.transform.GetChild(j); + // var childRes = BuildThroughTransform(go,child,j); + // if(childRes=="") continue; + // return $"/{id}{childRes}"; + // } + // } + // return ""; + // } + // public string BuildPath(Object go,GameObject[] roots){ + // + // //Search root objects + // for(int i=0;i= '0' and <= '9'){ + // var index = int.Parse(path[i]); + // currentGo = currentGo.transform.GetChild(index).gameObject; + // data.SetValue(s.FieldName,currentGo); + // } + // else{ + // isBehaviour = true; + // behaviour= currentGo.GetComponent(path[i]) as Behaviour; + // data.SetValue(s.FieldName,behaviour); + // } + // } + // else{ + // var index = int.Parse(path[i]); + // currentGo = currentGo?.transform?.GetChild(index).gameObject; + // } + // } + // } + // } + // } + // } + // } + + #endregion + + public override BlackboardData GetData(){ if (data == null) return null; + LoadBlackboardInfo(); if (!Cache.ContainsKey(this)){ Cache.Add(data,this); } - if (loadedFromScene==false){ loadedFromScene = true; + Load(); } - return data; } + + private void Load(){ + var res = SceneManager.GetActiveScene(); + GameObject.FindGameObjectsWithTag("SerializedData"); + } } } \ No newline at end of file diff --git a/TNode/Runtime/SceneSerializedData.cs b/TNode/Runtime/SceneSerializedData.cs new file mode 100644 index 0000000..906c7f1 --- /dev/null +++ b/TNode/Runtime/SceneSerializedData.cs @@ -0,0 +1,9 @@ +using UnityEngine; + +namespace TNode.Runtime{ + public class SceneSerializedData:MonoBehaviour{ + public GameObject serializedObject; + public Behaviour serializedFeature; + public bool isComponent; + } +} \ No newline at end of file diff --git a/TNode/Runtime/SceneSerializedData.cs.meta b/TNode/Runtime/SceneSerializedData.cs.meta new file mode 100644 index 0000000..b2b41a7 --- /dev/null +++ b/TNode/Runtime/SceneSerializedData.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 2f2dd6542406480ea3fec1d9527ffba8 +timeCreated: 1657874785 \ No newline at end of file diff --git a/TNode/RuntimeCache/RuntimeCache.cs b/TNode/RuntimeCache/RuntimeCache.cs index b46593a..cf0be53 100644 --- a/TNode/RuntimeCache/RuntimeCache.cs +++ b/TNode/RuntimeCache/RuntimeCache.cs @@ -16,33 +16,42 @@ namespace TNode.RuntimeCache{ } //delegate return a value from a nodedata public delegate object GetValueDelegate(IModel nodeData); - public delegate object SetValueDelegate(IModel nodeData,object value); + public delegate void SetValueDelegate(object nodeData,object value); public readonly Dictionary> CachedDelegatesForGettingValue = new (); - + public readonly Dictionary> CachedDelegatesForSettingValue = + new (); + private static readonly string[] ExcludedAssemblies = new string[]{"Microsoft", "UnityEngine","UnityEditor","mscorlib","System"}; public RuntimeCache(){ RegisterRuntimeBlackboard(typeof(EasyBlackboardData)); } public void RegisterRuntimeBlackboard(Type type){ + if (type == null) return; if(!CachedDelegatesForGettingValue.ContainsKey(type)){ CachedDelegatesForGettingValue.Add(type, new Dictionary()); + CachedDelegatesForSettingValue.Add(type,new Dictionary()); + var properties = type.GetProperties(); foreach(var property in properties){ //if the property only has a setter ,skip - if(property.GetMethod == null){ - continue; - } + var getValueDelegate = GetValueDelegateForProperty(property); CachedDelegatesForGettingValue[type].Add(property.Name,getValueDelegate); + + var setValueDelegate = SetValueDelegateForProperty(property); + CachedDelegatesForSettingValue[type].Add(property.Name,setValueDelegate); } //register the fields var fields = type.GetFields(); foreach(var field in fields){ var getValueDelegate = GetValueDelegateForField(field); CachedDelegatesForGettingValue[type].Add(field.Name,getValueDelegate); + + var setValueDelegate = SetValueDelegateForField(field); + CachedDelegatesForSettingValue[type].Add(field.Name,setValueDelegate); } } } @@ -50,15 +59,18 @@ namespace TNode.RuntimeCache{ private GetValueDelegate GetValueDelegateForField(FieldInfo field){ return field.GetValue; } - - + private SetValueDelegate SetValueDelegateForField(FieldInfo field){ + return field.SetValue; + } private GetValueDelegate GetValueDelegateForProperty(PropertyInfo property){ var getValueDelegate = (GetValueDelegate)Delegate.CreateDelegate(typeof(GetValueDelegate), property.GetGetMethod()); return getValueDelegate; } - - - + private SetValueDelegate SetValueDelegateForProperty(PropertyInfo property){ + var setValueDelegate = (SetValueDelegate)Delegate.CreateDelegate(typeof(SetValueDelegate), property.GetSetMethod()); + return setValueDelegate; + } + } public static class RuntimeExtension{ @@ -67,11 +79,18 @@ namespace TNode.RuntimeCache{ var method = RuntimeCache.Instance.CachedDelegatesForGettingValue[blackboardData.GetType()][path]; return (T) method.Invoke(blackboardData); } - public static object GetValue(this BlackboardData blackboardData, string path){ var method = RuntimeCache.Instance.CachedDelegatesForGettingValue[blackboardData.GetType()][path]; return method.Invoke(blackboardData); } + public static void SetValue(this BlackboardData blackboardData,string path,T value){ + var method = RuntimeCache.Instance.CachedDelegatesForSettingValue[blackboardData.GetType()][path]; + method.Invoke(blackboardData,value); + } + public static void SetValue(this BlackboardData blackboardData,string path,object value){ + var method = RuntimeCache.Instance.CachedDelegatesForSettingValue[blackboardData.GetType()][path]; + method.Invoke(blackboardData,value); + } public static RuntimeCache.GetValueDelegate GetValueDelegate(this BlackboardData blackboardData,string path){ var method = RuntimeCache.Instance.CachedDelegatesForGettingValue[blackboardData.GetType()][path]; return method; diff --git a/TNodeGraphViewImpl/Editor/GraphBlackboard/DefaultGraphBlackboardView.cs b/TNodeGraphViewImpl/Editor/GraphBlackboard/DefaultGraphBlackboardView.cs index e848d1c..ac22902 100644 --- a/TNodeGraphViewImpl/Editor/GraphBlackboard/DefaultGraphBlackboardView.cs +++ b/TNodeGraphViewImpl/Editor/GraphBlackboard/DefaultGraphBlackboardView.cs @@ -32,12 +32,13 @@ namespace TNodeGraphViewImpl.Editor.GraphBlackboard{ var foldoutData = new Foldout{ text = field.Name }; - var drawer = new PropertyField(serializedObject.FindProperty("data").FindPropertyRelative(field.Name),field.Name); + var drawer = new GraphBlackboardPropertyField(serializedObject.FindProperty("data").FindPropertyRelative(field.Name),field.Name); drawer.Bind(serializedObject); foldoutData.Add(drawer); visualElement.Add(propertyField); visualElement.Add(foldoutData); - this.Add(visualElement); + + Add(visualElement); } else{ diff --git a/TNodeGraphViewImpl/Editor/GraphBlackboard/GraphBlackboardPropertyField.cs b/TNodeGraphViewImpl/Editor/GraphBlackboard/GraphBlackboardPropertyField.cs new file mode 100644 index 0000000..fda833c --- /dev/null +++ b/TNodeGraphViewImpl/Editor/GraphBlackboard/GraphBlackboardPropertyField.cs @@ -0,0 +1,21 @@ +using UnityEditor; +using UnityEditor.UIElements; +using UnityEngine.UIElements; + +namespace TNodeGraphViewImpl.Editor.GraphBlackboard{ + public class GraphBlackboardPropertyField:PropertyField{ + public GraphBlackboardPropertyField(SerializedProperty findPropertyRelative, string fieldName):base(findPropertyRelative, fieldName){ + + } + + protected override void ExecuteDefaultActionAtTarget(EventBase evt) + { + base.ExecuteDefaultActionAtTarget(evt); + if (this.Q() != null){ + this.Q().allowSceneObjects = false; + } + } + + + } +} \ No newline at end of file diff --git a/TNodeGraphViewImpl/Editor/GraphBlackboard/GraphBlackboardPropertyField.cs.meta b/TNodeGraphViewImpl/Editor/GraphBlackboard/GraphBlackboardPropertyField.cs.meta new file mode 100644 index 0000000..c53a526 --- /dev/null +++ b/TNodeGraphViewImpl/Editor/GraphBlackboard/GraphBlackboardPropertyField.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 39e7ba9513c34ea0814f018befd8d7ad +timeCreated: 1657876733 \ No newline at end of file diff --git a/TextMesh Pro.meta b/TextMesh Pro.meta new file mode 100644 index 0000000..f9da8b5 --- /dev/null +++ b/TextMesh Pro.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f54d1bd14bd3ca042bd867b519fee8cc +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: