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

Общие вопросы о Unity3D

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

Сообщение Friend123 17 янв 2020, 11:29

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

Я прощупал 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, на котором будет висеть этот компонент с дефолтными значениями и при необходимости просто копировать этот компонент в нужные объекты пула.
Вроде бы вот этот способ подходит больше всего, но какого-то элегантного кода я не придумал и не нашел.

Может будут у кого какие соображения на сей счет? Буду только рад помощи.
Последний раз редактировалось Friend123 17 янв 2020, 14:44, всего редактировалось 1 раз.
Аватара пользователя
Friend123
Старожил
 
Сообщения: 701
Зарегистрирован: 26 фев 2012, 22:12
Откуда: Тверь
  • ICQ

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

Сообщение IDoNotExist 17 янв 2020, 11:54

Лучше всего в данном случае ИМХО отделять данные от логики, у вас должен быть отдельный контейнер со свойствами скрипта, который в данной задаче можно будет легко подменить на дефолтный.

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

private string defaultData;

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

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

Если важна производительность, можно этот вариант переделать на стандартную .NET сериализацию, должно быть побыстрее.
Аватара пользователя
IDoNotExist
Адепт
 
Сообщения: 1432
Зарегистрирован: 23 мар 2011, 09:18
Skype: iamnoexist

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

Сообщение Woolf 17 янв 2020, 12:33

Имхо, у компонента нет дефолтного состояния. Так что, способ, предложенный IDoNotExist совсем не дикий, а вполне нормальный.
Разработчик theFisherOnline - там, где клюёт
Разработчик Atom Fishing II - Первая 3D MMO про рыбалку
Разработчик Atom Fishing - Рыбалка на поплавок, донку, нахлыст, блесну в постъядерный период.
Аватара пользователя
Woolf
Адепт
 
Сообщения: 7179
Зарегистрирован: 02 мар 2009, 16:59

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

Сообщение Friend123 17 янв 2020, 13:27

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

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

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

Сообщение 1max1 17 янв 2020, 14:20

Также пробую через рефлексию, но пока не выходит:

Поля какие? Приватные?
Синтаксис:
Используется csharp
GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
Аватара пользователя
1max1
Адепт
 
Сообщения: 5505
Зарегистрирован: 28 июн 2017, 10:51

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

Сообщение Friend123 17 янв 2020, 14:44

Ребята, всем спасибо. Сделал через JSON, сработало. По производительности буду смотреть, но я думаю ощутимо не повлияет.
Аватара пользователя
Friend123
Старожил
 
Сообщения: 701
Зарегистрирован: 26 фев 2012, 22:12
Откуда: Тверь
  • ICQ


Вернуться в Общие вопросы

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 17