На следующем gif вы можете увидеть разницу между тем, как поля Vector3 ведут себя в инспекторе Transform и моих 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 должно делать что-то другое.
Когда я пытаюсь сделать то же самое в любом другом 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
Я даже пробовал GUILayout.MaxHeight(EditorGUIUtility.singleLineHeight), но это заставляет поле по-прежнему сворачиваться, но «загружаться»/перерисовываться в поле ниже.





Unity3d имеет свой исходный код, доступный на GitHub, где вы можете увидеть реализацию компонента Трансформировать.
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);
}
}
}
Я нашел соответствующие строки в Трансформинспектор
if (!EditorGUIUtility.wideMode)
{
EditorGUIUtility.wideMode = true;
EditorGUIUtility.labelWidth = EditorGUIUtility.currentViewWidth - 212;
}
EditorGUIUtility.wideMode выполняет две функции: Возвращает определяет, находится ли редактор в настоящее время является в широкоформатном режиме, и набор указывает, должен ли редактор для этого компонента/следующих строк вести себя так же, как в широкоформатном режиме. Таким образом, они просто заставляют свои поля «быть» только в широкополосном режиме.
После этого необходимо использовать «фиксированный» EditorGUIUtility.labelWidth, а именно уменьшенный на ширину, которую 3 поля Vectror3 будут занимать в широком режиме (Unity использовала 212)