Advertisement
zORg_alex

SceneView PropertyDrawer Editor

Nov 12th, 2024
56
0
Never
2
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 2.56 KB | Source Code | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using UnityEditor;
  5. using UnityEngine;
  6. using UnityEngine.SceneManagement;
  7. using Utility;
  8. using Object = UnityEngine.Object;
  9.  
  10. public static class SceneViewDrawerExtensions
  11. {
  12.     public abstract class Context<T, TContext>
  13.         where T : class
  14.         where TContext : Context<T, TContext>, new()
  15.     {
  16.         private static List<TContext> _subscribedEditors = new();
  17.         private TContext _self;
  18.         protected SerializedProperty _property;
  19.         protected T _field;
  20.         protected Object _object;
  21.         public bool IsEditing;
  22.  
  23.         private void Initialize(SerializedProperty property, TContext ctx)
  24.         {
  25.             _property = property;
  26.             _field = property.GetValue<T>();
  27.             _object = property.serializedObject.targetObject;
  28.             _self = ctx;
  29.         }
  30.         public static bool TrySubscribing(SerializedProperty property, out TContext ctx)
  31.         {
  32.             try //Applying or reverting changes destroys SerializedObject and there is no way to find this out
  33.             {
  34.                 ctx = _subscribedEditors?.FirstOrDefault(ctx => ctx._property.propertyPath == property.propertyPath);
  35.                 if (ctx != null) return false;
  36.             }
  37.             catch (Exception)
  38.             {
  39.                 _subscribedEditors.ToList().ForEach(ed => ed.UnsubscribeEditor());
  40.             }
  41.             ctx = new TContext();
  42.             ctx.Initialize(property, ctx);
  43.             ctx.SubscribeEditor();
  44.             _subscribedEditors.Add(ctx);
  45.             return true;
  46.         }
  47.         private void SubscribeEditor()
  48.         {
  49.             SceneView.duringSceneGui += OnSceneGUI;
  50.             Selection.selectionChanged += UnsubscribeEditor;
  51.             SceneManager.sceneUnloaded += UnsubscribeEditor;
  52.             AssemblyReloadEvents.beforeAssemblyReload += UnsubscribeEditor;
  53.         }
  54.  
  55.         private void UnsubscribeEditor(Scene arg0) => UnsubscribeEditor();
  56.         private void UnsubscribeEditor()
  57.         {
  58.             SceneView.duringSceneGui -= OnSceneGUI;
  59.             Selection.selectionChanged -= UnsubscribeEditor;
  60.             SceneManager.sceneUnloaded -= UnsubscribeEditor;
  61.             AssemblyReloadEvents.beforeAssemblyReload -= UnsubscribeEditor;
  62.             _subscribedEditors.Remove(_self);
  63.         }
  64.  
  65.         public static void StopEditingAll()
  66.         {
  67.             foreach (var ctx in _subscribedEditors)
  68.             {
  69.                 ctx.IsEditing = false;
  70.             }
  71.         }
  72.  
  73.         protected abstract void OnSceneGUI(SceneView view);
  74.  
  75.         public void GUIDrawEditButton(Rect rect)
  76.         {
  77.             GUI.color = IsEditing ? Color.red : Color.green;
  78.             if (!IsEditing && GUI.Button(rect, "Edit"))
  79.             {
  80.                 StopEditingAll();
  81.                 IsEditing = true;
  82.                 SceneView.RepaintAll();
  83.             }
  84.             else if (IsEditing && GUI.Button(rect, "Stop Editing"))
  85.             {
  86.                 IsEditing = false;
  87.                 SceneView.RepaintAll();
  88.             }
  89.             GUI.color = Color.white;
  90.         }
  91.     }
  92. }
Advertisement
Comments
  • zORg_alex
    8 days
    Comment was deleted
  • zORg_alex
    8 days (edited)
    # C# 4.09 KB | 0 0
    1. using RectEx;
    2. using System;
    3. using System.Collections.Generic;
    4. using Unity.Mathematics;
    5.  
    6. #if UNITY_EDITOR
    7. using UnityEditor;
    8. using UnityEditorInternal;
    9.  
    10. #endif
    11. using UnityEngine;
    12.  
    13. namespace Pickuppable
    14. {
    15.     /// <summary>
    16.     /// Example of using SceneViewDrawerExtensions
    17.     /// Packages/manifest.json:
    18.     /// {
    19.     ///   "dependencies": {
    20.     ///    "st.rect-ex": "https://github.com/slavniyteo/rect-ex.git#master"
    21.     /// }
    22.     /// Installed Git
    23.     /// </summary>
    24.     public class PickuppableAnimationInterface : MonoBehaviour
    25.     {
    26.         [SerializeField]
    27.         List<AnchorPoint> _anchorPoints;
    28.  
    29.         [Serializable]
    30.         public class AnchorPoint
    31.         {
    32.             public Vector3 localPosition;
    33.             public Quaternion localRotation = quaternion.identity;
    34.  
    35.             public Quaternion GetWorldRotation(Transform transform) => transform.rotation * localRotation;
    36.             public void SetWorldRotation(Quaternion rotation, Transform parent)
    37.             {
    38.                 localRotation = rotation * Quaternion.Inverse(parent.rotation);
    39.             }
    40.  
    41. #if UNITY_EDITOR
    42.             [CustomPropertyDrawer(typeof(AnchorPoint))]
    43.             public class AnchorPointInspector : PropertyDrawer
    44.             {
    45.                 private static float[] _weightsWithLabel = new float[] { 0, .15f, 1, .15f, 1, 0 };
    46.                 private static float[] _widthesWithLabel = new float[] { EditorGUIUtility.labelWidth, 0, 0, 0, 0, 80 };
    47.                 private static float[] _weightsWithNoLabel = new float[] { .15f, 1, .15f, 1, 0 };
    48.                 private static float[] _widthesWithNoLabel = new float[] { 0, 0, 0, 0, 80 };
    49.  
    50.                 public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    51.                 {
    52.  
    53.                     bool hideLabel = label.text.Length == 0;
    54.                     var rects = position.Row(weights: hideLabel ? _weightsWithNoLabel : _weightsWithLabel, widthes: hideLabel ? _widthesWithNoLabel : _widthesWithLabel);
    55.                     int i = 0;
    56.  
    57.                     if(!hideLabel)
    58.                         EditorGUI.LabelField(rects[i++], label);
    59.                     EditorGUI.BeginChangeCheck();
    60.  
    61.                     EditorGUI.LabelField(rects[i++], new GUIContent("pos"));
    62.                     EditorGUI.PropertyField(rects[i++], property.FindPropertyRelative(nameof(localPosition)), GUIContent.none);
    63.                     EditorGUI.LabelField(rects[i++], new GUIContent("rot"));
    64.                     EditorGUI.PropertyField(rects[i++], property.FindPropertyRelative(nameof(localRotation)), GUIContent.none);
    65.  
    66.                     if (EditorGUI.EndChangeCheck())
    67.                         property.serializedObject.ApplyModifiedProperties();
    68.  
    69.                     AnchorPointContext.TrySubscribing(property, out var ctx);
    70.                     ctx.GUIDrawEditButton(rects[i++]);
    71.                 }
    72.  
    73.                 private class AnchorPointContext : SceneViewDrawerExtensions.Context<AnchorPoint, AnchorPointContext>
    74.                 {
    75.                     private AnchorPoint _point => _field;
    76.                     private Transform _transform;
    77.                     protected override void OnSceneGUI(SceneView view)
    78.                     {
    79.                         if (!InternalEditorUtility.GetIsInspectorExpanded(_object))
    80.                             return;
    81.                         if (!_transform) _transform = ((MonoBehaviour)_object).transform;
    82.  
    83.                         Vector3 pos = _transform.TransformPoint(_point.localPosition);
    84.                         Quaternion rot = _point.GetWorldRotation(_transform);
    85.                         DrawEmpty(pos, rot);
    86.                         if (IsEditing && Tools.current == Tool.Move)
    87.                         {
    88.                             var newPos = Handles.PositionHandle(pos, rot);
    89.                             Vector3 newLocalPos = _transform.InverseTransformPoint(newPos);
    90.                             if (_point.localPosition == newLocalPos) return;
    91.                             Undo.RecordObject(_object, "HandPose MoveTool");
    92.                             _point.localPosition = newLocalPos;
    93.                         }
    94.                         else if (IsEditing && Tools.current == Tool.Rotate)
    95.                         {
    96.                             var newRot = Handles.RotationHandle(rot, pos);
    97.                             var newLocalRot = newRot * Quaternion.Inverse(_transform.rotation);
    98.                             if (_point.localRotation == newLocalRot) return;
    99.                             Undo.RecordObject(_object, "HandPose MoveTool");
    100.                             _point.localRotation = newLocalRot;
    101.                         }
    102.                     }
    103.  
    104.                     private void DrawEmpty(Vector3 pos, Quaternion rot)
    105.                     {
    106.                         Handles.color = Color.red;
    107.                         Handles.DrawAAPolyLine(pos, pos + rot * Vector3.right);
    108.                         Handles.color = Color.green;
    109.                         Handles.DrawAAPolyLine(pos, pos + rot * Vector3.up);
    110.                         Handles.color = Color.blue;
    111.                         Handles.DrawAAPolyLine(pos, pos + rot * Vector3.forward);
    112.                     }
    113.                 }
    114.             }
    115. #endif
    116.         }
    117.     }
    118. }
Add Comment
Please, Sign In to add comment
Advertisement