Показать сообщение отдельно
Старый 17.10.2020, 05:13   #17
Crystal
Терабайт исходников
 
Аватар для Crystal
 
Регистрация: 05.07.2007
Сообщений: 5,196
Написано 1,721 полезных сообщений
(для 5,374 пользователей)
Ответ: Очередные вопросы от меня по игровой логике и скриптингу

Сообщение от ABTOMAT Посмотреть сообщение
Ты имеешь в виду, каждый объект в Update проверяет каждый кадр, не пора ли ему удолиться? Это не самый производительный вариант, потому что проверка будет идти каждый кадр. Это не очень хорошо.

Вообще такое можно сделать 2 способами:

Через эвенты.

1. Создаёшь UnityEvent battleOver и вызываешь его battleOver.Invoke() в момент, когда битва завершена.
2. Каждому объекту, который имеет отношение к, в OnEnable делаешь подписку (лайк, колокольчик) на этот эвент:

battleOver.AddEventListener(() => {Debug.Log("Я отреагировал на завершение битвы!");}); 
Ну и соответственно в листенере можешь делать то действие, какое надо при завершении битвы (например, удалять этот объект).

Вариант с эвентами хорош тем, что можно создать эвенты на все ключевые события, а потом объекты "подписывать" на них по мере надобности.


Второй способ через списки:

Иметь список всех однотипных объектов и при надобности перебирать их все.
public static List<Monster> allMonsters = new List<Monster>(); // Глобальный список

Monster.allMonsters.Add(this); // Каждого монстра при создании (OnEnable) заносим в список 
Monster.allMonsters.Remove(this); // Каждого монстра при удалении (OnDisable) убираем из списка 
Соответственно при создании и удалении у тебя автоматом будут заноситься или убираться монстры в список.
Если тебе надо удалить всех монстров (или что-то с ними сделать) то перебираешь список:

Monster.allMonsters.ForEach(monster => {Debug.Log($"А мы тут монстров перебираем: {monster}!");}); 

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

В общем создал список:

    public static List<GameObject> Units = new List<GameObject>(); // Список монстров + игрок.
Запихиваю в него монстров:

FightScene.Units.Add(Monster); // Монстра заносим в список.
Если я из скрипта самого монстра хочу удалить его из листа и дестройнуть,
то пожалуйста, легко:

FightScene.Units.Remove(Monster);
Destroy(Monster);
но вот если я из другого следящего скрипта хочу
почистить всё из листа, без прямых ссылок на префаб монстра,
просто перебором, то я смогу только дестройнуть монстров,
оставив пустые строки в листе:

private int Listalo;
FightScene.Units.ForEach(Listalo => { if (Listalo == true) { Destroy(Listalo); }});
(да можно без if, не суть)

Так вот, конструкция выше прекрасно выпиливает все объекты в листе,
но оставляет вместо них пустышки, которые никуда из списка не исчезают.

Казалось бы, сделаем вот так и ок:

FightScene.Units.ForEach(Listalo => { if (Listalo == true) { Destroy(Listalo); FightScene.Units.Remove(Listalo); }});
И хрен, всё крашится в ошибку (Коллекция была изменена; операция перечисления может не выполняться.):
InvalidOperationException: Collection was modified; enumeration operation may not execute.
System.ThrowHelper.ThrowInvalidOperationException (System.ExceptionResource resource) (at <437ba245d8404784b9fbab9b439ac908>:0)
System.Collections.Generic.List`1[T].ForEach (System.Action`1[T] action) (at <437ba245d8404784b9fbab9b439ac908>:0)
GAMECONTROL.Update ()
Я бился с этим говном 10 часов, и не победил никакими способами.
__________________
Проект "Deathbring World - Rangers" и его финансовая поддержка:
https://boosty.to/deathbringrangers

Я на - TWITCH
Канал на YouTube
(Offline)
 
Ответить с цитированием