在以下gif中,您可以看到Vector3
和我的Transform
的检查器中MonoBehaviour
字段的行为方式。
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
字段将折叠为特定的Inspector宽度。
如何为我的字段获得与Transform
组件相同的行为-不折叠而是保持在同一行?
更新
我用GUILayout.MinWidth()
进行了尝试,但这没有任何改变。
根据建议,我也尝试过
example.vector3Value = EditorGUILayout.Vector3Field("Example", example.vector3Value, GUILayout.ExpandHeight(false));
(也适用于PropertyField()
),但没有任何改变。
而且我也尝试使用ExpandWidth(false)
... ...结果不是很令人满意:D
我什至尝试过GUILayout.MaxHeight(EditorGUIUtility.singleLineHeight)
,但这会使字段仍然折叠,但会在下面的字段中“重载” /透支。
答案 0 :(得分:1)
EditorGUILayout.Vector3Field
带有可选的第三个参数(GUILayoutOption
的数组),您可以在其中指定类似的内容。您需要传递以下内容:GUILayout.ExpandHeight(false)
答案 1 :(得分:1)
Unity3d在GitHub上有其source code,您可以在其中看到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);
}
}
}
答案 2 :(得分:1)
ScrollView
EditorGUIUtility.wideMode做两件事:返回当前编辑器是否处于宽屏模式,设置是否用于此组件/下一行的行为应与在宽模式下相同。因此,他们只是强制其字段仅在宽屏模式下“存在”。
此后,有必要使用“固定” EditorGUIUtility.labelWidth,即减小宽度的3 if (!EditorGUIUtility.wideMode)
{
EditorGUIUtility.wideMode = true;
EditorGUIUtility.labelWidth = EditorGUIUtility.currentViewWidth - 212;
}
字段将采用宽模式(Unity使用212)