3

在下面的 gif 中,您可以看到Vector3字段在 Inspector ofTransform和 my MonoBehaviours 中的行为方式之间的区别。

在此处输入图像描述

Transform甚至是CustomEditor我也使用EditorGUILayout.Vector3Field().

[CustomEditor(typeof(Transform), true)]
[CanEditMultipleObjects]
public class AdvancedTransformEditor : Editor
{
    //Unity's built-in editor
    private Editor _defaultEditor;
    private Transform _transform;

    private void OnEnable()
    {
        //When this inspector is created, also create the built-in inspector
        _defaultEditor = CreateEditor(targets, Type.GetType("UnityEditor.TransformInspector, UnityEditor"));
        _transform = target as Transform;
    }

    private void OnDisable()
    {
        //When OnDisable is called, the default editor we created should be destroyed to avoid memory leakage.
        //Also, make sure to call any required methods like OnDisable
        var disableMethod = _defaultEditor.GetType().GetMethod("OnDisable", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
        if (disableMethod != null) disableMethod.Invoke(_defaultEditor, null);
        DestroyImmediate(_defaultEditor);
    }

    public override void OnInspectorGUI()
    {
        EditorGUILayout.LabelField("Local Space", EditorStyles.boldLabel);
        _defaultEditor.OnInspectorGUI();

        serializedObject.Update();

        //Show World Space Transform
        EditorGUILayout.Space();
        EditorGUILayout.LabelField("World Space", EditorStyles.boldLabel);

        _transform.position = EditorGUILayout.Vector3Field("Position", _transform.position);

        EditorGUI.BeginDisabledGroup(true);
        EditorGUILayout.Vector3Field("Rotation", _transform.eulerAngles);
        EditorGUILayout.Vector3Field("Scale", _transform.lossyScale);
        EditorGUI.EndDisabledGroup();

        serializedObject.ApplyModifiedProperties();
    }
}

它只有_defaultEditor.OnInspectorGUI();在 Unity 的原始编辑器中为Transform组件做一些不同的事情时才有效。

当我尝试在其他任何地方做同样的事情CustomEditorMonoBehaviour

// without a CustomEditor
public class Example : MonoBehaviour
{
    public Vector3 example;
}

// Width the custom editor
public class ExampleMinWidth : MonoBehaviour
{
    public Vector3 example;
}

[CustomEditor(typeof(ExampleMinWidth))]
public class ExampleMinWidthEditor : Editor
{
    private SerializedProperty example;

    private void OnEnable()
    {
        example = serializedObject.FindProperty("exmaple");
    }

    public override void OnInspectorGUI()
    {
        serializedObject.Update();
        example.vector3Value = EditorGUILayout.Vector3Field("Example", example.vector3Value);

        // I tried both also simply using a PropertyField
        //EditorGUILayout.PropertyField(example);
        serializedObject.ApplyModifiedProperties();
    }
}

或跳过字段_defaultEditor.OnInspectorGUI();AdvancedTransformEditor的行Vector3会折叠一定的检查器宽度。

如何使我的字段与Transform组件具有相同的行为 - 不折叠但保持在同一行?


更新

  • 我试过了,GUILayout.MinWidth()但这并没有改变任何东西。

  • 正如建议的那样,我也尝试过

    example.vector3Value = EditorGUILayout.Vector3Field("Example", example.vector3Value, GUILayout.ExpandHeight(false));
    

    (也适用于PropertyField()),但这并没有改变任何东西。

  • 只是为了尝试,我也做了ExpandWidth(false)......结果不是很令人愉快:D

    在此处输入图像描述

  • 我什至尝试过GUILayout.MaxHeight(EditorGUIUtility.singleLineHeight),但这使得该字段仍然折叠但“bload”/overdraw 进入下面的字段。

4

2 回答 2

1

Unity3d在 GitHub 上提供了其源代码,您可以在其中看到Transform组件的实现。

TransformInspector.cs:

/ Unity C# reference source
// Copyright (c) Unity Technologies. For terms of use, see
// https://unity3d.com/legal/licenses/Unity_Reference_Only_License

using UnityEngine;

namespace UnityEditor
{
    [CustomEditor(typeof(Transform))]
    [CanEditMultipleObjects]
    internal class TransformInspector : Editor
    {
        SerializedProperty m_Position;
        SerializedProperty m_Scale;
        TransformRotationGUI m_RotationGUI;

        class Contents
        {
            public GUIContent positionContent = EditorGUIUtility.TrTextContent("Position", "The local position of this GameObject relative to the parent.");
            public GUIContent scaleContent = EditorGUIUtility.TrTextContent("Scale", "The local scaling of this GameObject relative to the parent.");
            public string floatingPointWarning = LocalizationDatabase.GetLocalizedString("Due to floating-point precision limitations, it is recommended to bring the world coordinates of the GameObject within a smaller range.");
        }
        static Contents s_Contents;

        public void OnEnable()
        {
            m_Position = serializedObject.FindProperty("m_LocalPosition");
            m_Scale = serializedObject.FindProperty("m_LocalScale");

            if (m_RotationGUI == null)
                m_RotationGUI = new TransformRotationGUI();
            m_RotationGUI.OnEnable(serializedObject.FindProperty("m_LocalRotation"), EditorGUIUtility.TrTextContent("Rotation", "The local rotation of this GameObject relative to the parent."));
        }

        public override void OnInspectorGUI()
        {
            if (s_Contents == null)
                s_Contents = new Contents();

            if (!EditorGUIUtility.wideMode)
            {
                EditorGUIUtility.wideMode = true;
                EditorGUIUtility.labelWidth = EditorGUIUtility.currentViewWidth - 212;
            }

            serializedObject.Update();

            Inspector3D();
            // Warning if global position is too large for floating point errors.
            // SanitizeBounds function doesn't even support values beyond 100000
            Transform t = target as Transform;
            Vector3 pos = t.position;
            if (Mathf.Abs(pos.x) > 100000 || Mathf.Abs(pos.y) > 100000 || Mathf.Abs(pos.z) > 100000)
                EditorGUILayout.HelpBox(s_Contents.floatingPointWarning, MessageType.Warning);

            serializedObject.ApplyModifiedProperties();
        }

        private void Inspector3D()
        {
            EditorGUILayout.PropertyField(m_Position, s_Contents.positionContent);
            m_RotationGUI.RotationField();
            EditorGUILayout.PropertyField(m_Scale, s_Contents.scaleContent);
        }
    }
}
于 2019-02-21T19:01:24.627 回答
1

我在TransformInspector中找到了相关行

if (!EditorGUIUtility.wideMode)
{
    EditorGUIUtility.wideMode = true;
    EditorGUIUtility.labelWidth = EditorGUIUtility.currentViewWidth - 212;
}
  • EditorGUIUtility.wideMode做了两件事:返回编辑器当前是否处于宽模式,并设置该组件/下一行的编辑器是否应该像在宽模式下一样。所以他们只是强制他们的领域只在宽模式下“存在”。

  • 之后,有必要使用“固定的” EditorGUIUtility.labelWidth,即减少 3 个Vectror3字段在宽模式下将采用的宽度(Unity 使用 212)

于 2019-02-21T19:11:33.843 回答