• UnityEditor 实现如 BoxCollider 的编辑功能


    image
    CastShapeBase.cs

    点击查看代码
    using System.Collections;
    using UnityEngine;
    
    public abstract class CastShapeBase : MonoBehaviour {
    
    #if UNITY_EDITOR
        protected readonly Color m_gizomsColor = Color.cyan;
    
        protected virtual void Reset () {
    
        }
    
        protected virtual void OnDrawGizmosSelected () {
    
        }
    #endif
    }
    

    CastBox.cs

    using System.Collections;
    using UnityEngine;
    
    public class CastBox : CastShapeBase {
    
        public Vector3 center;
        public Vector3 size = Vector3.one;
    
    #if UNITY_EDITOR
        protected override void Reset () {
            center = Vector3.zero;
            size = Vector3.one;
        }
    
        protected override void OnDrawGizmosSelected () {
            Matrix4x4 gizmosMatrixRecord = Gizmos.matrix;
            Color gizmosColorRecord = Gizmos.color;
            Gizmos.color = m_gizomsColor;
            Gizmos.matrix = transform.localToWorldMatrix;
            Gizmos.DrawWireCube(center, size);
            Gizmos.color = gizmosColorRecord;
            Gizmos.matrix = gizmosMatrixRecord;
        }
    #endif
    }
    

    CastBoxEditor.cs 放置在名为 Editor 的文件夹下

    #if UNITY_EDITOR
    using System.Collections;
    using UnityEditor;
    using UnityEditor.EditorTools;
    using UnityEditor.IMGUI.Controls;
    using UnityEngine;
    
    [EditorTool("Edit Cast Shape", typeof(CastBox))]
    public class CastBoxTool : CastShapeTool<CastBox> {
    
        private readonly BoxBoundsHandle m_boundsHandle = new BoxBoundsHandle();
    
        protected override PrimitiveBoundsHandle boundsHandle {
            get { return m_boundsHandle; }
        }
    
        protected override void CopyColliderPropertiesToHandle (CastBox castShape) {
            m_boundsHandle.center = TransformColliderCenterToHandleSpace(castShape.transform, castShape.center);
            m_boundsHandle.size = Vector3.Scale(castShape.size, castShape.transform.lossyScale);
        }
    
        protected override void CopyHandlePropertiesToCollider (CastBox castShape) {
            castShape.center = TransformHandleCenterToColliderSpace(castShape.transform, m_boundsHandle.center);
            Vector3 size = Vector3.Scale(m_boundsHandle.size, InvertScaleVector(castShape.transform.lossyScale));
            size = new Vector3(Mathf.Abs(size.x), Mathf.Abs(size.y), Mathf.Abs(size.z));
            castShape.size = size;
        }
    }
    
    
    [CustomEditor(typeof(CastBox))]
    [CanEditMultipleObjects]
    public class CastBoxEditor : Editor {
    
        private SerializedProperty m_script;
        private SerializedProperty m_center;
        private SerializedProperty m_size;
    
        private void OnEnable () {
            m_script = serializedObject.FindProperty("m_Script");
            m_center = serializedObject.FindProperty("center");
            m_size = serializedObject.FindProperty("size");
        }
    
        public override void OnInspectorGUI () {
            serializedObject.Update();
    
            GUI.enabled = false;
            EditorGUILayout.PropertyField(m_script);
            GUI.enabled = true;
            EditorGUILayout.EditorToolbarForTarget(EditorGUIUtility.TrTempContent("Edit Shape"), target);
            EditorGUILayout.PropertyField(m_center);
            EditorGUILayout.PropertyField(m_size);
    
            serializedObject.ApplyModifiedProperties();
        }
    }
    #endif
    

    CastShapeTool.cs 旋转在名为 Editor 的文件夹下

    点击查看代码
    #if UNITY_EDITOR
    using System.Collections;
    using System.Reflection;
    using UnityEditor;
    using UnityEditor.EditorTools;
    using UnityEditor.IMGUI.Controls;
    using UnityEngine;
    
    public abstract class CastShapeTool<T> : EditorTool where T : CastShapeBase {
    
        protected readonly Color m_handleEnableColor = Color.cyan;
        protected readonly Color m_handleDisableColor = new Color(0f, 0.7f, 0.7f);
    
        public override GUIContent toolbarIcon {
            get {
                PropertyInfo propertyInfo = typeof(PrimitiveBoundsHandle).GetProperty("editModeButton", BindingFlags.NonPublic | BindingFlags.Static);
                return (GUIContent)propertyInfo.GetValue(null);
            }
        }
    
        protected abstract PrimitiveBoundsHandle boundsHandle { get; }
    
        protected abstract void CopyColliderPropertiesToHandle (T castShape);
    
        protected abstract void CopyHandlePropertiesToCollider (T castShape);
    
        protected Vector3 InvertScaleVector (Vector3 scaleVector) {
            for (int axis = 0; axis < 3; ++axis)
                scaleVector[axis] = scaleVector[axis] == 0f ? 0f : 1f / scaleVector[axis];
    
            return scaleVector;
        }
    
        public override void OnToolGUI (EditorWindow window) {
            foreach (var obj in targets) {
                if (!(obj is T castShape) || Mathf.Approximately(castShape.transform.lossyScale.sqrMagnitude, 0f))
                    continue;
    
                // collider matrix is center multiplied by transform's matrix with custom postmultiplied lossy scale matrix
                using (new Handles.DrawingScope(Matrix4x4.TRS(castShape.transform.position, castShape.transform.rotation, Vector3.one))) {
                    CopyColliderPropertiesToHandle(castShape);
    
                    boundsHandle.SetColor(castShape.enabled ? m_handleEnableColor : m_handleDisableColor);
    
                    EditorGUI.BeginChangeCheck();
    
                    boundsHandle.DrawHandle();
    
                    if (EditorGUI.EndChangeCheck()) {
                        Undo.RecordObject(castShape, string.Format("Modify {0}", ObjectNames.NicifyVariableName(target.GetType().Name)));
                        CopyHandlePropertiesToCollider(castShape);
                    }
                }
            }
        }
    
        protected static Vector3 TransformColliderCenterToHandleSpace (Transform colliderTransform, Vector3 colliderCenter) {
            return Handles.inverseMatrix * (colliderTransform.localToWorldMatrix * colliderCenter);
        }
    
        protected static Vector3 TransformHandleCenterToColliderSpace (Transform colliderTransform, Vector3 handleCenter) {
            return colliderTransform.localToWorldMatrix.inverse * (Handles.matrix * handleCenter);
        }
    }
    #endif
    
  • 相关阅读:
    蓝桥杯——一步之遥,扩展gcd的应用
    质数唯一分解定理应用——多个数的最小公约数和最大公倍数
    蓝桥杯训练 ——天平称重
    蓝桥杯 奇怪的捐赠——进制的运用
    Kubernetes-基本概念
    Docker-基本概念
    虚拟化向容器化发展
    Kubernetes-服务连接和暴露(endpoints资源)
    Kubernetes-NodePort
    Kubernetes-Load Balancer
  • 原文地址:https://www.cnblogs.com/kingBook/p/15939749.html
Copyright © 2020-2023  润新知