Мои Уведомления
Привет, !
Мой Аккаунт Мои Финансы Мои Подписки Мои Настройки Выход
Руководство API скрипты

SerializedObject

класс в UnityEditor

Описание

SerializedObject и SerializedProperty — это классы для редактирования сериализованных полей в объектах Unity совершенно общим способом. Эти классы автоматически обрабатывают загрязнение отдельных сериализованных полей, поэтому они будут обработаны системой Undo и правильно оформлены для переопределений Prefab при рисовании в Инспекторе.

Во многих случаях вы можете создавать инструменты для изменения объектов в вашем проекте. Например, в следующем примере скрипта создается пункт меню, который сбрасывает локальную позицию всех выбранных в данный момент игровых объектов. Поместите его в файл с именем Example1.cs в папке с именем Editor:

using UnityEditor; using UnityEngine;

static class Example1 { [MenuItem("Edit/Reset Selected Objects Position (No Undo)")] static void ResetPosition() { // this action will not be undoable foreach (var go in Selection.gameObjects) go.transform.localPosition = Vector3.zero; } }

Хотя таким образом вы можете редактировать объекты через их API-точки, вам также придется использовать другие API-интерфейсы редактора, чтобы указать, какие компоненты были изменены, чтобы это действие нельзя было выполнить и оно было обнаружено как изменение в следующий раз, когда Сцена сохраняется и так далее. Напротив, использование SerializedObject обрабатывает этот процесс автоматически. Следующий пример сценария имеет тот же эффект, что и предыдущий, но его также нельзя отменить, и он отслеживается как изменение сцены. Поместите его в файл с именем Example2.cs в папке с именем Editor:

using System.Linq; using UnityEditor; using UnityEngine;

static class Example2 { [MenuItem("Edit/Reset Selected Objects Position")] static void ResetPosition() { var transforms = Selection.gameObjects.Select(go => go.transform).ToArray(); var so = new SerializedObject(transforms); // you can Shift+Right Click on property names in the Inspector to see their paths so.FindProperty("m_LocalPosition").vector3Value = Vector3.zero; so.ApplyModifiedProperties(); } }

SerializedObject одновременно открывает поток данных для одного или нескольких целевых объектов Unity, что позволяет одновременно редактировать сериализованные данные, общие для объектов. Например, если у вас есть несколько Behaviours разных типов в потоке данных, единственным общим свойством для них может быть "m_Enabled".

Когда вы впервые создайте экземпляр SerializedObject, чтобы он был актуальным. Любые изменения, которые вы вносите в SerializedProperty, доступные в этом потоке данных, в конечном итоге должны быть сброшены с помощью метода SerializedObject.ApplyModifiedProperties. Если вы храните ссылку на экземпляр SerializedObject для более чем одного фрейма, вы должны вручную вызвать его метод SerializedObject.Update, прежде чем читать из него какие-либо данные, поскольку один или несколько целевых объектов могли быть изменены в другом месте, например, в отдельном потоке SerializedObject. Соответственно, обратите внимание, что два разных потока SerializedObject с одними и теми же целевыми объектами независимы друг от друга, и вы должны вручную синхронизировать их таким образом, если один или несколько из них поддерживаются в течение нескольких кадров.

Одним из наиболее распространенных применений классов SerializedObject и SerializedProperty является создание пользовательских редакторов, где использование SerializedObject является рекомендуемый подход, а не непосредственное изменение проверяемых целевых объектов.

В следующем примере сценария определяется компонент, который анимирует локальное положение объекта с помощью функции синуса. Поместите его в скрипт под названием SineAnimation.cs:

using UnityEngine;

public class SineAnimation : MonoBehaviour { public Vector3 axis { get { return m_Axis; } set { m_Axis = value; } } [SerializeField] private Vector3 m_Axis = Vector3.up;

public float period { get { return m_Period; } set { m_Period = value; } } [SerializeField] private float m_Period = 1f / Mathf.PI;

public float amplitude { get { return m_Amplitude; } set { m_Amplitude = value; } } [SerializeField] private float m_Amplitude = 1f;

public float phaseShift { get { return m_PhaseShift; } set { m_PhaseShift = Mathf.Clamp01(value); } } [SerializeField, Range(0f, 1f)] private float m_PhaseShift;

void Update() { transform.localPosition = m_Axis * m_Amplitude * Mathf.Sin((Time.time + m_PhaseShift) / m_Period); }

void OnValidate() { m_PhaseShift = Mathf.Clamp01(m_PhaseShift); } }

В следующем примере сценария определяется пользовательский редактор для SineAnimation, который добавляет кнопку после элементов управления по умолчанию для рандомизации параметров синусоидальной функции. Поместите его в файл с именем SineAnimationEditor.cs в папке с именем Editor:

using UnityEditor; using UnityEngine;

[CustomEditor(typeof(SineAnimation)), CanEditMultipleObjects] public class SineAnimationEditor : Editor { public override void OnInspectorGUI() { base.OnInspectorGUI(); if (GUILayout.Button("Randomize Sine Function", EditorStyles.miniButton)) { serializedObject.FindProperty("m_Period").floatValue = Random.Range(0f, 10f); serializedObject.FindProperty("m_Amplitude").floatValue = Random.Range(0f, 10f); serializedObject.FindProperty("m_PhaseShift").floatValue = Random.Range(0f, 1f); serializedObject.ApplyModifiedProperties(); } } }

Класс Editor имеет свойство serializedObject, которое обеспечивает поток для всех проверяемых целей (компоненты SineAnimation в в данном случае), что позволяет легко поддерживать одновременное редактирование нескольких объектов. Поскольку этот экземпляр SerializedObject сохраняется в течение всего времени существования экземпляра Editor, базовая реализация OnInspectorGUI обрабатывает вызов Update перед рисованием любых элементов управления, а также вызов ApplyModifiedProperties после любого взаимодействия с пользователем. Таким образом, все изменения, сделанные при нажатии кнопки, добавленной в этот инспектор, должны быть сброшены с помощью ApplyModifiedProperties перед выходом из метода, иначе они будут потеряны при следующей базовой реализации Editor.OnInspectorGUI вызывает метод SerializedObject.Update для экземпляра serializedObject.

Обратите внимание, что передача данных в объект Unity через SerializedObject.ApplyModifiedProperties не будет учитывать логику проверки данных, которая может быть у вас в установщиках свойств, связанных с сериализованными полями. В этом примере значение поля «m_PhaseShift» фиксируется между 0 и 1 как в установщике свойства PhaseShift, так и в пользовательском интерфейсе (через RangeAttribute). Поскольку пользователи могут получить доступ к 'm_PhaseShift' через SerializedProperty (а также путем редактирования ресурса на диске), а не только через API 'phaseShift' или пользовательский интерфейс, необходимо также зафиксируйте его в допустимом диапазоне в обратном вызове MonoBehaviour.OnValidate, который будет очищать данные при загрузке объекта Unity. .

Также обратите внимание, что хотя SerializedObject предназначен для работы с несколькими целевыми объектами, свойства получателя значений в классе SerializedProperty (например, floatValue, vector3Value) не поддерживает множественный выбор. Таким образом, присвоение им значения повлияет на все цели, но чтение значения из них возвращает только значение, связанное с первой целью в списке.

Смотрите так же: SerializedProperty, SerializeField, Editor, MonoBehaviour.OnValidate, hasMultipleDifferentValues.

Свойства

context Контекст, используемый для хранения и разрешения типов ExposedReference. Это задается конструктором SerializedObject.
hasModifiedProperties Истинно, если SerializedObject имеет измененное свойство, которое не было применено.
isEditingMultipleObjects Представляет ли сериализованный объект несколько объектов из-за редактирования нескольких объектов? (Только чтение)
maxArraySizeForMultiEditing Определяет максимальный размер, после которого нельзя редактировать массивы при выборе нескольких объектов.
targetObject Просматриваемый объект (только для чтения).
targetObjects Проверяемые объекты (только для чтения).

Конструкторы

SerializedObject Создаёт SerializedObject для проверяемого объекта.

Публичные Методы

ApplyModifiedProperties Применить изменения свойств.
ApplyModifiedPropertiesWithoutUndoотмены Применяет изменения свойств без регистрации операции отмены.
CopyFromSerializedProperty Копирует значение из SerializedProperty в соответствующее сериализованное свойство сериализованного объекта.
CopyFromSerializedPropertyIfDifferent Копирует измененное значение из SerializedProperty в соответствующее сериализованное свойство сериализованного объекта.
FindProperty Поиск сериализованного свойства по имени.
GetIterator Получить первое сериализованное свойство.
SetIsDifferentCacheDirty Обновить кэш hasMultipleDifferentValues ​​при следующем вызове /Update()/.
Update Обновить представление сериализованного объекта.
UpdateIfRequiredOrScript Обновить представление сериализованного объекта, только если объект был изменен с момента последнего вызова Update или если это скрипт.
Вы можете отблагодарить автора, за перевод документации на русский язык. ₽ Спасибо
API скрипты 2021.3