Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using UnityEditor;
- using UnityEngine;
- using UnityEngine.SceneManagement;
- using Utility;
- using Object = UnityEngine.Object;
- public static class SceneViewDrawerExtensions
- {
- public abstract class Context<T, TContext>
- where T : class
- where TContext : Context<T, TContext>, new()
- {
- private static List<TContext> _subscribedEditors = new();
- private TContext _self;
- protected SerializedProperty _property;
- protected T _field;
- protected Object _object;
- public bool IsEditing;
- private void Initialize(SerializedProperty property, TContext ctx)
- {
- _property = property;
- _field = property.GetValue<T>();
- _object = property.serializedObject.targetObject;
- _self = ctx;
- }
- public static bool TrySubscribing(SerializedProperty property, out TContext ctx)
- {
- try //Applying or reverting changes destroys SerializedObject and there is no way to find this out
- {
- ctx = _subscribedEditors?.FirstOrDefault(ctx => ctx._property.propertyPath == property.propertyPath);
- if (ctx != null) return false;
- }
- catch (Exception)
- {
- _subscribedEditors.ToList().ForEach(ed => ed.UnsubscribeEditor());
- }
- ctx = new TContext();
- ctx.Initialize(property, ctx);
- ctx.SubscribeEditor();
- _subscribedEditors.Add(ctx);
- return true;
- }
- private void SubscribeEditor()
- {
- SceneView.duringSceneGui += OnSceneGUI;
- Selection.selectionChanged += UnsubscribeEditor;
- SceneManager.sceneUnloaded += UnsubscribeEditor;
- AssemblyReloadEvents.beforeAssemblyReload += UnsubscribeEditor;
- }
- private void UnsubscribeEditor(Scene arg0) => UnsubscribeEditor();
- private void UnsubscribeEditor()
- {
- SceneView.duringSceneGui -= OnSceneGUI;
- Selection.selectionChanged -= UnsubscribeEditor;
- SceneManager.sceneUnloaded -= UnsubscribeEditor;
- AssemblyReloadEvents.beforeAssemblyReload -= UnsubscribeEditor;
- _subscribedEditors.Remove(_self);
- }
- public static void StopEditingAll()
- {
- foreach (var ctx in _subscribedEditors)
- {
- ctx.IsEditing = false;
- }
- }
- protected abstract void OnSceneGUI(SceneView view);
- public void GUIDrawEditButton(Rect rect)
- {
- GUI.color = IsEditing ? Color.red : Color.green;
- if (!IsEditing && GUI.Button(rect, "Edit"))
- {
- StopEditingAll();
- IsEditing = true;
- SceneView.RepaintAll();
- }
- else if (IsEditing && GUI.Button(rect, "Stop Editing"))
- {
- IsEditing = false;
- SceneView.RepaintAll();
- }
- GUI.color = Color.white;
- }
- }
- }
Advertisement
Comments
-
Comment was deleted
-
- using RectEx;
- using System;
- using System.Collections.Generic;
- using Unity.Mathematics;
- #if UNITY_EDITOR
- using UnityEditor;
- using UnityEditorInternal;
- #endif
- using UnityEngine;
- namespace Pickuppable
- {
- /// <summary>
- /// Example of using SceneViewDrawerExtensions
- /// Packages/manifest.json:
- /// {
- /// "dependencies": {
- /// "st.rect-ex": "https://github.com/slavniyteo/rect-ex.git#master"
- /// }
- /// Installed Git
- /// </summary>
- public class PickuppableAnimationInterface : MonoBehaviour
- {
- [SerializeField]
- List<AnchorPoint> _anchorPoints;
- [Serializable]
- public class AnchorPoint
- {
- public Vector3 localPosition;
- public Quaternion localRotation = quaternion.identity;
- public Quaternion GetWorldRotation(Transform transform) => transform.rotation * localRotation;
- public void SetWorldRotation(Quaternion rotation, Transform parent)
- {
- localRotation = rotation * Quaternion.Inverse(parent.rotation);
- }
- #if UNITY_EDITOR
- [CustomPropertyDrawer(typeof(AnchorPoint))]
- public class AnchorPointInspector : PropertyDrawer
- {
- private static float[] _weightsWithLabel = new float[] { 0, .15f, 1, .15f, 1, 0 };
- private static float[] _widthesWithLabel = new float[] { EditorGUIUtility.labelWidth, 0, 0, 0, 0, 80 };
- private static float[] _weightsWithNoLabel = new float[] { .15f, 1, .15f, 1, 0 };
- private static float[] _widthesWithNoLabel = new float[] { 0, 0, 0, 0, 80 };
- public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
- {
- bool hideLabel = label.text.Length == 0;
- var rects = position.Row(weights: hideLabel ? _weightsWithNoLabel : _weightsWithLabel, widthes: hideLabel ? _widthesWithNoLabel : _widthesWithLabel);
- int i = 0;
- if(!hideLabel)
- EditorGUI.LabelField(rects[i++], label);
- EditorGUI.BeginChangeCheck();
- EditorGUI.LabelField(rects[i++], new GUIContent("pos"));
- EditorGUI.PropertyField(rects[i++], property.FindPropertyRelative(nameof(localPosition)), GUIContent.none);
- EditorGUI.LabelField(rects[i++], new GUIContent("rot"));
- EditorGUI.PropertyField(rects[i++], property.FindPropertyRelative(nameof(localRotation)), GUIContent.none);
- if (EditorGUI.EndChangeCheck())
- property.serializedObject.ApplyModifiedProperties();
- AnchorPointContext.TrySubscribing(property, out var ctx);
- ctx.GUIDrawEditButton(rects[i++]);
- }
- private class AnchorPointContext : SceneViewDrawerExtensions.Context<AnchorPoint, AnchorPointContext>
- {
- private AnchorPoint _point => _field;
- private Transform _transform;
- protected override void OnSceneGUI(SceneView view)
- {
- if (!InternalEditorUtility.GetIsInspectorExpanded(_object))
- return;
- if (!_transform) _transform = ((MonoBehaviour)_object).transform;
- Vector3 pos = _transform.TransformPoint(_point.localPosition);
- Quaternion rot = _point.GetWorldRotation(_transform);
- DrawEmpty(pos, rot);
- if (IsEditing && Tools.current == Tool.Move)
- {
- var newPos = Handles.PositionHandle(pos, rot);
- Vector3 newLocalPos = _transform.InverseTransformPoint(newPos);
- if (_point.localPosition == newLocalPos) return;
- Undo.RecordObject(_object, "HandPose MoveTool");
- _point.localPosition = newLocalPos;
- }
- else if (IsEditing && Tools.current == Tool.Rotate)
- {
- var newRot = Handles.RotationHandle(rot, pos);
- var newLocalRot = newRot * Quaternion.Inverse(_transform.rotation);
- if (_point.localRotation == newLocalRot) return;
- Undo.RecordObject(_object, "HandPose MoveTool");
- _point.localRotation = newLocalRot;
- }
- }
- private void DrawEmpty(Vector3 pos, Quaternion rot)
- {
- Handles.color = Color.red;
- Handles.DrawAAPolyLine(pos, pos + rot * Vector3.right);
- Handles.color = Color.green;
- Handles.DrawAAPolyLine(pos, pos + rot * Vector3.up);
- Handles.color = Color.blue;
- Handles.DrawAAPolyLine(pos, pos + rot * Vector3.forward);
- }
- }
- }
- #endif
- }
- }
- }
Add Comment
Please, Sign In to add comment
Advertisement