Страница 1 из 1

Сбросить компонент в дефолтное состояние скриптом [РЕШЕНО]

СообщениеДобавлено: 17 янв 2020, 11:29
Friend123
Добрый день, коллеги.
Казалось бы простой вопрос - а как сбросить кастомный компонент в изначальное состояние из скрипта?
Мне это нужно для приведения в исходное состояние объекта из пула объектов в том случае, когда он деактивируется (например, юнит уничтожен).

Я прощупал 3 варианта:
1. Удалить, добавить
Синтаксис:
Используется csharp
Destroy(gameObject.GetComponent<GameObjectAnimator>());
gameObject.AddComponent<GameObjectAnimator>();
 

Этот способ не подошел, т.к. теряются ссылки (но их конечно можно восстановить) и в целом работа становится странной, долго разбирался, но так и не понял почему при такой операции с компонентом практически невозможно работать.

2. Есть метод Reset из мануала https://docs.unity3d.com/ScriptReference/MonoBehaviour.Reset.html?_ga=2.187018474.392052278.1579246470-594371806.1568297886, но он работает только в рамках редактора, поэтому тоже мимо.

3. Есть также мысль, чтобы при создании объекта где-то записать/хранить дефолтные значения компонента, а потом при деактивации объекта эти дефолтные значения заменить на текущие.
Либо создать отдельный GameObject, на котором будет висеть этот компонент с дефолтными значениями и при необходимости просто копировать этот компонент в нужные объекты пула.
Вроде бы вот этот способ подходит больше всего, но какого-то элегантного кода я не придумал и не нашел.

Может будут у кого какие соображения на сей счет? Буду только рад помощи.

Re: Сбросить компонент в дефолтное состояние скриптом

СообщениеДобавлено: 17 янв 2020, 11:54
IDoNotExist
Лучше всего в данном случае ИМХО отделять данные от логики, у вас должен быть отдельный контейнер со свойствами скрипта, который в данной задаче можно будет легко подменить на дефолтный.

P.S. Еще есть довольно дикий вариант:
Синтаксис:
Используется csharp

private string defaultData;

void Awake()
{
    defaultData = JsonUtility.ToJson(this);
}

void Reset()
{
    JsonUtility.JsonUtility.FromJsonOverwrite(defaultData, this);
}
 

Если важна производительность, можно этот вариант переделать на стандартную .NET сериализацию, должно быть побыстрее.

Re: Сбросить компонент в дефолтное состояние скриптом

СообщениеДобавлено: 17 янв 2020, 12:33
Woolf
Имхо, у компонента нет дефолтного состояния. Так что, способ, предложенный IDoNotExist совсем не дикий, а вполне нормальный.

Re: Сбросить компонент в дефолтное состояние скриптом

СообщениеДобавлено: 17 янв 2020, 13:27
Friend123
Да, я нашел тут данный вариант с JSON, но не пробовал его еще. Вроде как пишут, что он не быстрый, но надо проверить.

Также пробую через рефлексию, но пока не выходит:
Синтаксис:
Используется csharp
GameObjectAnimator OrigComponent = GameObject.Find("OriginalGOA").GetComponent<GameObjectAnimator>();
foreach (System.Reflection.FieldInfo f in OrigComponent.GetType().GetFields()) {
    f.SetValue(_objectOnMap, f.GetValue(OrigComponent));
}
 

Re: Сбросить компонент в дефолтное состояние скриптом

СообщениеДобавлено: 17 янв 2020, 14:20
1max1
Также пробую через рефлексию, но пока не выходит:

Поля какие? Приватные?
Синтаксис:
Используется csharp
GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);

Re: Сбросить компонент в дефолтное состояние скриптом

СообщениеДобавлено: 17 янв 2020, 14:44
Friend123
Ребята, всем спасибо. Сделал через JSON, сработало. По производительности буду смотреть, но я думаю ощутимо не повлияет.