diff --git a/Experimental/DistributedAuthoritySample/Assets/Scripts/Editor/AvatarTransformEditor.cs b/Experimental/DistributedAuthoritySample/Assets/Scripts/Editor/AvatarTransformEditor.cs deleted file mode 100644 index 05c8f487a..000000000 --- a/Experimental/DistributedAuthoritySample/Assets/Scripts/Editor/AvatarTransformEditor.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Unity.Multiplayer.Samples.SocialHub.Player; -using UnityEditor; -using UnityEditor.UIElements; -using UnityEngine; -using UnityEngine.UIElements; - -namespace Unity.Multiplayer.Samples.SocialHub.Editor -{ - [CustomEditor(typeof(AvatarTransform))] - class AvatarTransformEditor : UnityEditor.Editor - { - public override VisualElement CreateInspectorGUI() - { - // Create a new VisualElement to be the root of the inspector UI - var root = new VisualElement(); - - // Generate default inspector for AvatarTransform - serializedObject.Update(); - SerializedProperty property = serializedObject.GetIterator(); - property.NextVisible(true); // Skip the script field - while (property.NextVisible(false)) - { - var propertyField = new PropertyField(property); - root.Add(propertyField); - } - - serializedObject.ApplyModifiedProperties(); - - return root; - } - } -} diff --git a/Experimental/DistributedAuthoritySample/Assets/Scripts/Editor/AvatarTransformEditor.cs.meta b/Experimental/DistributedAuthoritySample/Assets/Scripts/Editor/AvatarTransformEditor.cs.meta deleted file mode 100644 index 8f91d7dee..000000000 --- a/Experimental/DistributedAuthoritySample/Assets/Scripts/Editor/AvatarTransformEditor.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 2ad6787b48af94939adc8213c08bd3eb \ No newline at end of file diff --git a/Experimental/DistributedAuthoritySample/Assets/Scripts/Editor/BaseObjectMotionHandlerEditor.cs b/Experimental/DistributedAuthoritySample/Assets/Scripts/Editor/BaseObjectMotionHandlerEditor.cs new file mode 100644 index 000000000..937b05d28 --- /dev/null +++ b/Experimental/DistributedAuthoritySample/Assets/Scripts/Editor/BaseObjectMotionHandlerEditor.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using Unity.Multiplayer.Samples.SocialHub.Physics; +using UnityEditor; +using UnityEditor.UIElements; +using UnityEngine; +using UnityEngine.UIElements; + +namespace Unity.Multiplayer.Samples.SocialHub.Editor +{ + [CanEditMultipleObjects] + [CustomEditor(typeof(BaseObjectMotionHandler), editorForChildClasses: true)] + class BaseObjectMotionHandlerEditor : UnityEditor.Editor + { + HashSet m_DrawnFields = new HashSet(); + + public override VisualElement CreateInspectorGUI() + { + var root = new VisualElement(); + + Type currentType = target.GetType(); + var types = new List(); + + // Gather all types up to MonoBehaviour + while (currentType != typeof(MonoBehaviour) && currentType != null) + { + types.Add(currentType); + currentType = currentType.BaseType; + } + + // Iterate types in reverse (base class first) + types.Reverse(); + + foreach (var type in types) + { + Foldout foldout = CreateFoldoutForType(serializedObject, type); + root.Add(foldout); + } + + root.Bind(serializedObject); + return root; + } + + Foldout CreateFoldoutForType(SerializedObject obj, Type type) + { + var foldout = new Foldout { text = type.Name }; + + // Check for custom drawing method + MethodInfo customDrawMethod = type.GetMethod("CreateInspectorGUI", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly); + if (customDrawMethod != null && type != typeof(BaseObjectMotionHandler)) // ie. only include overriden methods + { + VisualElement customElement = (VisualElement)customDrawMethod.Invoke(obj.targetObject, new object[] { obj }); + foldout.Add(customElement); + return foldout; + } + + // Fallback to default drawing if no custom drawing method is found + FieldInfo[] fieldInfos = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly); + foreach (var fieldInfo in fieldInfos) + { + if (m_DrawnFields.Contains(fieldInfo.Name)) + { + continue; + } + + SerializedProperty property = obj.FindProperty(fieldInfo.Name); + if (property != null) + { + var propertyField = new PropertyField(property); + foldout.Add(propertyField); + m_DrawnFields.Add(fieldInfo.Name); + } + } + + return foldout; + } + } +} diff --git a/Experimental/DistributedAuthoritySample/Assets/Scripts/Editor/BaseObjectMotionHandlerEditor.cs.meta b/Experimental/DistributedAuthoritySample/Assets/Scripts/Editor/BaseObjectMotionHandlerEditor.cs.meta new file mode 100644 index 000000000..d20a78f05 --- /dev/null +++ b/Experimental/DistributedAuthoritySample/Assets/Scripts/Editor/BaseObjectMotionHandlerEditor.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 560496b5b70864696af25892030dd249 \ No newline at end of file diff --git a/Experimental/DistributedAuthoritySample/Assets/Scripts/Editor/DestructibleObjectEditor.cs b/Experimental/DistributedAuthoritySample/Assets/Scripts/Editor/DestructibleObjectEditor.cs deleted file mode 100644 index 0070c2487..000000000 --- a/Experimental/DistributedAuthoritySample/Assets/Scripts/Editor/DestructibleObjectEditor.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Unity.Multiplayer.Samples.SocialHub.Gameplay; -using UnityEditor; -using UnityEditor.UIElements; -using UnityEngine; -using UnityEngine.UIElements; - -namespace Unity.Multiplayer.Samples.SocialHub.Editor -{ - [CustomEditor(typeof(DestructibleObject))] - class DestructibleObjectEditor : UnityEditor.Editor - { - public override VisualElement CreateInspectorGUI() - { - // Create a new VisualElement to be the root of the inspector UI - var root = new VisualElement(); - - // Generate default inspector for AvatarTransform - serializedObject.Update(); - SerializedProperty property = serializedObject.GetIterator(); - property.NextVisible(true); // Skip the script field - while (property.NextVisible(false)) - { - var propertyField = new PropertyField(property); - root.Add(propertyField); - } - - serializedObject.ApplyModifiedProperties(); - - return root; - } - } -} diff --git a/Experimental/DistributedAuthoritySample/Assets/Scripts/Editor/DestructibleObjectEditor.cs.meta b/Experimental/DistributedAuthoritySample/Assets/Scripts/Editor/DestructibleObjectEditor.cs.meta deleted file mode 100644 index 63681d1be..000000000 --- a/Experimental/DistributedAuthoritySample/Assets/Scripts/Editor/DestructibleObjectEditor.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: c4746eccfea8d4378a13a35effd619c1 diff --git a/Experimental/DistributedAuthoritySample/Assets/Scripts/Editor/PhysicsObjectMotionEditor.cs b/Experimental/DistributedAuthoritySample/Assets/Scripts/Editor/PhysicsObjectMotionEditor.cs deleted file mode 100644 index 2393faeec..000000000 --- a/Experimental/DistributedAuthoritySample/Assets/Scripts/Editor/PhysicsObjectMotionEditor.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Unity.Multiplayer.Samples.SocialHub.Physics; -using UnityEngine; -using UnityEditor; -using UnityEditor.UIElements; -using UnityEngine.UIElements; - -namespace Unity.Multiplayer.Samples.SocialHub.Editor -{ - [CustomEditor(typeof(PhysicsObjectMotion))] - class PhysicsObjectMotionEditor : UnityEditor.Editor - { - public override VisualElement CreateInspectorGUI() - { - // Create a new VisualElement to be the root of the inspector UI - var root = new VisualElement(); - - // Generate default inspector for AvatarTransform - serializedObject.Update(); - SerializedProperty property = serializedObject.GetIterator(); - property.NextVisible(true); // Skip the script field - while (property.NextVisible(false)) - { - var propertyField = new PropertyField(property); - root.Add(propertyField); - } - - serializedObject.ApplyModifiedProperties(); - - return root; - } - } -} diff --git a/Experimental/DistributedAuthoritySample/Assets/Scripts/Editor/PhysicsObjectMotionEditor.cs.meta b/Experimental/DistributedAuthoritySample/Assets/Scripts/Editor/PhysicsObjectMotionEditor.cs.meta deleted file mode 100644 index 199590052..000000000 --- a/Experimental/DistributedAuthoritySample/Assets/Scripts/Editor/PhysicsObjectMotionEditor.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 6513302c68bd64368883bcb638331607 \ No newline at end of file diff --git a/Experimental/DistributedAuthoritySample/Assets/Scripts/Editor/Unity.Multiplayer.Samples.SocialHub.Editor.asmdef b/Experimental/DistributedAuthoritySample/Assets/Scripts/Editor/Unity.Multiplayer.Samples.SocialHub.Editor.asmdef index d8015d3b5..5cb09c35a 100644 --- a/Experimental/DistributedAuthoritySample/Assets/Scripts/Editor/Unity.Multiplayer.Samples.SocialHub.Editor.asmdef +++ b/Experimental/DistributedAuthoritySample/Assets/Scripts/Editor/Unity.Multiplayer.Samples.SocialHub.Editor.asmdef @@ -17,4 +17,4 @@ "defineConstraints": [], "versionDefines": [], "noEngineReferences": false -} \ No newline at end of file +} diff --git a/Experimental/DistributedAuthoritySample/Assets/Scripts/Physics/BaseObjectMotionHandler.cs b/Experimental/DistributedAuthoritySample/Assets/Scripts/Physics/BaseObjectMotionHandler.cs index 0aa5ec66d..4d524162a 100644 --- a/Experimental/DistributedAuthoritySample/Assets/Scripts/Physics/BaseObjectMotionHandler.cs +++ b/Experimental/DistributedAuthoritySample/Assets/Scripts/Physics/BaseObjectMotionHandler.cs @@ -4,6 +4,11 @@ using Unity.Netcode.Components; using UnityEngine; using System.Collections.Generic; +#if UNITY_EDITOR +using UnityEditor; +using UnityEditor.UIElements; +using UnityEngine.UIElements; +#endif namespace Unity.Multiplayer.Samples.SocialHub.Physics { @@ -367,5 +372,29 @@ protected void LogMessage(string msg, bool forceMessage = false, float messageTi } #endregion + +#if UNITY_EDITOR + // override this in child classes to implement custom drawing of a child class' inspector + protected virtual VisualElement CreateInspectorGUI(SerializedObject serializedObj) + { + // Create a new VisualElement to be the root of our inspector UI. + var root = new VisualElement(); + + // Iterate through the properties of the serialized object. + SerializedProperty property = serializedObj.GetIterator(); + property.NextVisible(true); // Skip the script property. + + while (property.NextVisible(false)) + { + // Create a PropertyField for each visible property. + var propertyField = new PropertyField(property); + propertyField.BindProperty(property); + root.Add(propertyField); + } + + // Return the finished UI. + return root; + } +#endif } }