Прежде чем начать общее примечание, потому что вы упомянули его в своем вопросе:
По возможности, я настоятельно рекомендую вообще не использовать target
! В частности, не устанавливайте поля напрямую. это делает такие вещи, как маркировка вашей сцены direty и, таким образом, сохранение изменений, а также функциональность Undo / Redo довольно сложной, поскольку вам придется реализовать ее самостоятельно!
Скорее всегда go - SerializedProperty
в сочетании с SerializedObject.Update
и SerializedObject.ApplyModifiedProperties
(примеры будут приведены ниже). Это обрабатывает все такие вещи, как маркировка dirty и, таким образом, сохранение изменений сцены и автоматического отмены / возврата для вас!
Затем в TextArea.
Позволяет сказать у вас есть такой класс, как
public class Example : MonoBehaviour
{
[SerializeField] private string _exampleString;
public string AnotherExampleString;
}
В основном есть три основных варианта. Сначала я сделаю скрипт Editor
(custom Inspector), так как вы немного более гибки.
Ниже будет EditorWindow
.
На самом деле вам даже не понадобится Editor
скрипт вообще! Просто пометьте соответствующие поля как [TextArea]
следующим образом:
public class Example : MonoBehaviour
{
[SerializeField] [TextArea] private string _exampleString;
// You can also directly configure the min and max line count here as well
// By default it is 3 lines
[TextAre(3,7)] public string AnotherExampleString;
}
Это уже выглядит следующим образом
Затем Если Вам все еще нужен сценарий Editor
, то хорошая вещь о EditorGUILayout.PropertyField
автоматически использует правильный ящик для соответствующего типа ... и также применяет все атрибуты редактора ! Разве это не здорово?
Так просто иметь и Editor
как
[CustomEditor(typeof(Example))]
public class ExampleEditor : Editor
{
private SerializedProperty _exampleString;
private SerializedProperty AnotherExampleString;
private void OnEnable()
{
// Link in the serialized properties to their according fields
_exampleString = serializedObject.FindProperty("_exampleString");
AnotherExampleString = serializedObject.FindProperty("AnotherExampleString");
}
public override void OnInspectorGUI()
{
DrawScriptField();
// load the real target values into the serialized properties
serializedObject.Update();
EditorGUILayout.PropertyField(_exampleString);
EditorGUILayout.PropertyField(AnotherExampleString);
// write back the changed properties into the real target
serializedObject.ApplyModifiedProperties();
}
// Little bonus from my side so you have the script field on top
private void DrawScriptField()
{
EditorGUI.BeginDisabledGroup(true);
EditorGUILayout.ObjectField("Script", MonoScript.FromMonoBehaviour((Example)target), typeof(Example), false);
EditorGUILayout.Space();
EditorGUI.EndDisabledGroup();
}
}
Результат выглядит в основном точно так же:
Используя EditorGUILayout.TextArea
, вы можете отобразить любой string
как мульти текстовая область Это также относится к EditorWindow
.
Скажем еще раз, что мы не пометили наши string
поля
public class Example : MonoBehaviour
{
[SerializeField] private string _exampleString;
public string AnotherExampleString;
}
Но мы можем заставить их отображаться так же, как и до этого Editor
script:
[CustomEditor(typeof(Example))]
public class ExampleEditor : Editor
{
private SerializedProperty _exampleString;
private SerializedProperty AnotherExampleString;
private Vector2 scroll1;
private Vector2 scroll2;
private void OnEnable()
{
// Link in the serialized properties to their according fields
_exampleString = serializedObject.FindProperty("_exampleString");
AnotherExampleString = serializedObject.FindProperty("AnotherExampleString");
}
public override void OnInspectorGUI()
{
DrawScriptField();
// load the real target values into the serialized properties
serializedObject.Update();
EditorGUILayout.PrefixLabel(_exampleString.displayName);
scroll1 = EditorGUILayout.BeginScrollView(scroll1,GUILayout.MaxHeight(3 * EditorGUIUtility.singleLineHeight));
_exampleString.stringValue = EditorGUILayout.TextArea(_exampleString.stringValue, EditorStyles.textArea);
EditorGUILayout.EndScrollView();
EditorGUILayout.PrefixLabel(AnotherExampleString.displayName);
scroll2 = EditorGUILayout.BeginScrollView(scroll2, GUILayout.MaxHeight(7 * EditorGUIUtility.singleLineHeight));
AnotherExampleString.stringValue = EditorGUILayout.TextArea(AnotherExampleString.stringValue);
EditorGUILayout.EndScrollView();
// write back the changed properties into the real target
serializedObject.ApplyModifiedProperties();
}
// Little bonus from my side so you have the script field on top
private void DrawScriptField()
{
EditorGUI.BeginDisabledGroup(true);
EditorGUILayout.ObjectField("Script", MonoScript.FromMonoBehaviour((Example)target), typeof(Example), false);
EditorGUILayout.Space();
EditorGUI.EndDisabledGroup();
}
}
Хотя вы можете видеть, что нам уже пришлось немного подделать его, используя дополнительные EditorGUILayout.BeginScrollView
Это то же самое, что вы можете также сделать в EditorWindow
. В большинстве случаев не имеет смысла go - SerializedProperty
для EditorWindow
public class ExampleWindow : EditorWindow
{
private string exampleString;
private Vector2 scroll;
[MenuItem("Example/Show ExampleWindow")]
private static void Initialize()
{
var window = GetWindow<ExampleWindow>();
window.Show();
}
private void OnGUI()
{
EditorGUILayout.PrefixLabel("Example String");
scroll = EditorGUILayout.BeginScrollView(scroll,GUILayout.MaxHeight(3 * EditorGUIUtility.singleLineHeight));
exampleString = EditorGUILayout.TextArea(exampleString, EditorStyles.textArea);
EditorGUILayout.EndScrollView();
}
}
, что приводит к