Как заставить поля Vector3 вести себя так же, как поля из Transform в CustomEditor - PullRequest
0 голосов
/ 21 февраля 2019

В следующем GIF-файле вы можете увидеть разницу между поведением полей Vector3 в инспекторе Transform и моих MonoBehaviour с.

enter image description here

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 для 10101* компонент должен делать что-то другое.

Когда я пытаюсь сделать то же самое в любом другом CustomEditor для MonoBehaviour

// 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

    enter image description here

  • Я даже пытался GUILayout.MaxHeight(EditorGUIUtility.singleLineHeight), но это заставляет поле все еще складываться, но "bload" / overdraw в поле ниже.

Ответы [ 3 ]

0 голосов
/ 21 февраля 2019

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);
        }
    }
}
0 голосов
/ 21 февраля 2019

Я нашел соответствующие строки в TransformInspector

if (!EditorGUIUtility.wideMode)
{
    EditorGUIUtility.wideMode = true;
    EditorGUIUtility.labelWidth = EditorGUIUtility.currentViewWidth - 212;
}
  • EditorGUIUtility.wideMode делает две вещи: Returns является ли редактор в настоящее время в широкоэкранном режиме и устанавливает , должен ли редактор для этого компонента / следующих строк вести себя так же, как в широкоформатном режиме.Таким образом, они просто заставляют свои поля только «быть» в широкоэкранном режиме.

  • После этого необходимо использовать «фиксированный» EditorGUIUtility.labelWidth , а именно уменьшенный наширина поля 3 Vectror3 будут широкоформатными (используется Unity 212)

0 голосов
/ 21 февраля 2019

EditorGUILayout.Vector3Field принимает необязательный третий аргумент (массив GUILayoutOption), где вы можете указать такие вещи.Вы хотите передать в этом: GUILayout.ExpandHeight(false)

...