как перезапустить скрипт unity
Unity C# — Как сделать перезапуск уровня при падении персонажа в пропасть?
Ну уровень то вам не обязательно выгружать и загружать заново. Просто верните по событию «персонаж упал» все величины в нужных скриптах на стартовую позицию. То есть, конечно надо учесть в скриптах, что они могут быть «сброшены» на начальное значение, создать метод сброса или задавать переменным значения на Start() а после его вызывать.
PS: для проверки упал ли, можно разместить Collider, Trigger и при соприкосновении, OnTriggerEnter(), вызывать метод перезапуска уровня (сброса параметров).
Вот какое-то видео на эту тему, но наверное можно найти и посвежей https://youtu.be/OcmqVmg28F0
Не получается=( что не так?
Не получается=( что не так?
Идите посмотрите обучающие уроки, поймите принципы и как что работает.
интереснее.
но как и что устроенно, про проверки в каждом кадре, что за чем вызывается и тд..
вам бы выучить
и формулировать вопросы бы научиться) как то более формализированно)))
сэкономите и себе и людям времени кучу и нервов)
При перезапуске сцены, скрипт сохраняет прошлые значения, а не обновляется полностью. Что делать?
Помощь в написании контрольных, курсовых и дипломных работ здесь.
Исключение MissingReferenceException при перезапуске сцены
MissingReferenceException: The object of type ‘Transform’ has been destroyed but you are still.
Ubuntu 18.04.3. Как применить скрипт для обновления iptables при перезапуске системы?
Создаём инициализирующий скрипт с дампом правил iptables: nano /etc/firewall.v4.init Копируем в.
При нажатии кнопки полностью обновляется страница
У меня есть форма с 2 input’ами и кнопкой. При нажатии кнопки информация из этих инпутов.
Запомнить значения TextBox при перезапуске программы
Есть текст боксы в которые я ввожу значения,они передаются на другую форму и записываются в.
Пока что только учусь. Сделал как вы и написали, объекты перестали ускоряться. Просто стали постоянно падать с одной и той же скоростью.
Добавлено через 24 минуты
Или можно например какой другой код написать для ускоренного падения?
Решение
Добавлено через 1 минуту
А это случайно не игра с бомбочками по видеоуроку? типа «делаем игру за 40 минут»?
Добавлено через 3 минуты
ну точно, она Я просто прикрутил счетчик очков и уменьшал delay между бомбами в зависимости от счетчика
Скрипт висит на префабе объекта. А сама игра по типу видео за 45 минут. Я смотрел это видео, там у него бомбочки падали сверху, а мне нужно вот тоже самое только чтобы со временем их скорость увеличивалась. Не мало времени мучаюсь с этим моментом, что не напишу, либо скорость сохраняется, а не увеличивается, либо при перезапуске сцены(нажав на всплывающую кнопку) скорость сохраняется и дальше продолжает набирать обороты. А мне бы так сделать чтобы при рестарте набранная скорость за прошлый раз сбрасывалась и заново набирала её.
Добавлено через 42 минуты
В общем написал вот такой скрипт и прикрепил его на кнопку рестар и на префаб объекта, вроде всё заработало. Благодарю за выделенное вами мне времени.
Помощь в написании контрольных, курсовых и дипломных работ здесь.
Запомнить значения RichTextBox при перезапуске программы
Доброго времени суток! Наткнулся на грабли, не могу реализовать сохранение вписанного текста.
Функция rand() выдает одни и те же значения при перезапуске приложения
Привет, товарищи! Столкнулся я с проблемкой, которую никак не получается решить. Гугл не помогает.
Вирус полностью заблокировал компьютер:( что делать?
Вообщем вылезло окно мол ваш компьютер заблокирован! для снятия блокировки Вам необходимо оплатить.
Прошлые значения поля
Здравствуйте. Есть таблица tbl1 и к ней форма. Как сделать чтобы при изменении значения в поле.
Настройка порядка выполнения скриптов
По умолчанию, функции Awake, OnEnable и Update расположенные в разных скриптах вызываются в том порядке, в котором загружаются сами скрипты (т.е. в неопределенном). Тем не менее, существует возможность изменить этот порядок при помощи настройки порядка выполнения скриптов ( Script Execution Order ).
Добавить скрипты в инспектор можно при помощи кнопки плюс “+” и перетягивания для изменения их относительного порядка. Обратите внимание, что существует возможность переместить скрипт как выше, так и ниже полоски Default Time (время по умолчанию); те, что над ней, будут выполнены до “времени по умолчанию”, а те, что ниже, выполнятся после. Порядок расположения скриптов в диалоговом окне сверху вниз определяет их порядок выполнения. Все остальные скрипты, не указанные в диалоговом окне, будут выполнены в момент “времени по умолчанию” и в неопределенном (случайном) порядке.
Числа, расположенные рядом с каждым скриптом, являются фактическими значениями по которым определяется порядок выполнения. В момент, когда скрипт передвинут в новую позицию, число рядом с этим скриптом автоматически изменяется соответственно. Когда происходит ручное или автоматическое изменение числа, то в мета файл этого скрипта вносятся изменения. По этой причине, чем меньше чисел изменяется при модификации порядка, тем лучше. Именно поэтому, вместо того, чтобы присваивать новые значение всем скриптам, изменения происходят, по возможности, только в тех скриптах, которые были перемещены.
Методы организации взаимодействия между скриптами в Unity3D
Вступление
Подход 1. Назначение через редактор Unity3D
Пусть у нас в проекте есть два скрипта. Первый скрип отвечает за начисление очков в игре, а второй за пользовательский интерфейс, который, отображает количество набранных очков на экране игры.
Назовем оба скрипта менеджерами: ScoresManager и HUDManager.
Каким же образом менеджеру, отвечающему за меню экрана можно получить текущее количество очков от менеджера, отвечающего за начисление очков?
Предполагается, что в иерархии объектов(Hierarchy) сцены существуют два объекта, на один из которых назначен скрипт ScoresManager, а на другой скрипт HUDManager.
Один из подходов, содержит следующий принцип:
В скрипте UIManager определяем переменную типа ScoresManager:
Но переменную ScoresManager необходимо еще инициализировать экземпляром класса. Для этого выберем в иерархии объектов объект, на который назначен скрипт HUDManager и в настройках объекта увидим переменную ScoresManager со значением None.
Далее, из окна иерархии перетаскиваем объект, содержащий скрипт ScoresManager в область, где написано None и назначаем его объявленной переменной:
После чего, у нас появляется возможность из кода HUDManager обращаться к скрипту ScoresManager, таким образом:
Все просто, но игра, не ограничивается одними набранными очками, HUD может отображать текущие жизни игрока, меню доступных действия игрока, информацию о уровне и многое другое. Игра может насчитывать в себе десятки и сотни различных скриптов, которым нужно получать информацию друг от друга.
Чтобы получить в одном скрипте данные из другого скрипта нам каждый раз придется описывать переменную в одном скрипте и назначать (перетаскивать вручную) ее с помощью редактора, что само по себе нудная работа, которую легко можно забыть сделать и потом долго искать какая из переменных не инициализирована.
Если мы захотим что-то отрефакторить, переименовать скрипт, то все старые инициализации в иерархии объектов, связанные с переименованным скриптом, сбросятся и придется их назначать снова.
В то же время, такой механизм не работает для префабов (prefab) — динамического создания объектов из шаблона. Если какому-либо префабу нужно обращаться к менеджеру, расположенному в иерархии объектов, то вы не сможете назначить самому префабу элемент из иерархии, а придется сначала создать объект из префаба и после этого программно присвоить экземпляр менеджера переменной только что созданного объекта. Не нужная работа, не нужный код, дополнительная связанность.
Следующий подход решает все эти проблемы.
Подход 2. «Синглтоны»
Применим упрощенную классификацию возможных скриптов, которые используются при создании игры. Первый тип скриптов: «скрипты-менеджеры», второй: «скрипты-игровые-объекты».
Основное отличие одних от других в том, что «скрипты-менеджеры» всегда имеют единственный экземпляр в игре, в то время как «скрипты-игровые-объекты» могут иметь количество экземпляров больше единицы.
Примеры
Как правило, в единственном экземпляре существуют скрипты, отвечающие за общую логику пользовательского интерфейса, за проигрывание музыки, за отслеживание условий завершения уровня, за управление системой заданий, за отображение спецэффектов и так далее.
В то же время, скрипты игровых объектов существуют в большом количестве экземпляров: каждая птичка из «Angry Birds» управляется экземпляром скрипта птички со своим уникальным состоянием; для любого юнита в стратегии создается экземпляр скрипта юнита, содержащий его текущее количество жизней, позицию на поле и личную цель; поведение пяти разных иконок обеспечивается различными экземплярами одних и тех же скриптов, отвечающих за это поведение.
В примере из предыдущего шага скрипты HUDManager и ScoresManager всегда существуют в единственном экземпляре. Для их взаимодействия друг с другом применим паттерн «синглтон» (Singleton, он же одиночка).
В классе ScoresManager опишем статическое свойство типа ScoresManager, в котором будет храниться единственный экземпляр менеджера очков:
Осталось инициализировать свойство Instance экземпляром класса, который создает среда Unity3D. Так как ScoresManager наследник MonoBehaviour, то он участвует в жизненном цикле всех активных скриптов в сцене и во время инициализации скрипта у него вызывается метод Awake. В этот метод мы и поместить код инициализации свойства Instance:
После чего, использовать ScoresManager из других скриптов можно следующим образом:
Теперь нет необходимости в HUDManager описывать поле типа ScoresManager и назначать его в редакторе Unity3D, любой «скрипт-менеджер» может предоставлять доступ к себе через статическое свойство Instance, которое будет инициализировать в функции Awake.
Плюсы
— нет необходимости описывать поле скрипта и назначать его через редактор Unity3D.
— можно смело рефакторить код, если что и отвалится, то компилятор даст знать.
— к другим «скриптам-менеджерам» теперь можно обращаться из префабов, через свойство Instance.
Минусы
— подход обеспечивает доступ только к «скриптам-менеджерам», существующим в единственном экземпляре.
— сильная связанность.
На последнем «минусе» остановимся подробнее.
Пусть мы разрабатываем игру, в которой есть персонажи (unit) и эти персонажи могут погибать (die).
Где-то находится участок кода, который проверяет не погиб ли наш персонаж:
Получается, что персонаж после совей смерти должен разослать всем компонентам, которые в ней заинтересованы этот печальный факт, он должен знать о существовании этих компонентов и должен знать, что они им интересуются. Не слишком ли много знаний, для маленького юнита?
Так как игра, по логике, очень связанная структура, то и события происходящие в других компонентах интересуют третьи, юнит тут ничем не особенный.
Примеры таких событий (далеко не все):
— Условие прохождение уровня зависит от количества набранных очков, набрали 1000 очков – прошли уровень (LevelConditionManager связан с ScoresManager).
— Когда набираем 500 очков, достигаем важную стадию прохождения уровня, нужно проиграть веселую мелодию и визуальный эффект (ScoresManager связан с EffectsManager и SoundsManager).
— Когда персонаж восстанавливает здоровье, нужно проиграть эффект лечения над картинкой персонажа в панели персонажа (UnitsPanel связан с EffectsManager).
— и так далее.
В результате таких связей мы приходим к картине похожей на следующую, где все про всех все знают:
Пример со смертью персонажа немного преувеличен, сообщать о смерти (или другом событии) шести разным компонентам не так часто приходится. Но варианты, когда при каком-то событии в игре, функция, в которой произошло событие, сообщает об этом 2-3 другим компонентам встречается сплошь и рядом по всему коду.
Следующий подход пытается решает эту проблему.
Подход 3. Мировой эфир (Event Aggregator)
Введем специальный компонент «EventAggregator», основная функция которого хранить список событий, происходящих в игре.
Событие в игре — это функционал, предоставляющий любому другому компоненту возможность как подписаться на себя, так и опубликовать факт совершения этого события. Реализация функционала события может быть любой на вкус разработчика, можно использовать стандартные решения языка или написать свою реализацию.
Пример простой реализации события из прошлого примера (о смерти юнита):
Добавляем это событие в «EventAggregator»:
Теперь, функция Die из предыдущего примера с восемью строчками преобразуется в функцию с одной строчкой кода. Нам нет необходимости сообщать о том, что юнит умер всем заинтересованным компонентам и знать о этих заинтересованных. Мы просто публикуем факт свершения события:
А любой компонент, которому интересно это событие, может отреагировать на него следующим образом (на примере менеджера отвечающего за количество набранных очков):
В функции Awake менеджер подписывается на событие и передает делегат, отвечающий за обработку этого события. Сам же обработчик события, принимает в качестве параметра экземпляр умершего юнита и добавляет количество очков в зависимости от типа этого юнита.
Таким же образом, все другие компоненты, кому интересно событие смерти юнита, могут подписаться на него и обработать, когда событие произойдет.
В результате, диаграмма связей между компонентами, когда каждая компонента знала друг о друге, превращается в диаграмму, когда компоненты знают только о событиях, которые происходят в игре (только о интересующих их событиях), но им все равно, от куда эти события пришли. Новая диаграмма будет выглядеть следующим образом:
Замечание
Говоря, что никакой другой код не меняется, я конечно немножко лукавлю. Может оказаться так, что систему достижений интересуют события, которые ранее просто не публиковались в игре, потому как ни одну другую систему до этого не интересовали. И в этом случае, нам нужно будет решить какие новые события добавить в игру и кто будет их публиковать. Но в идеальной игре уже все возможные события есть и эфир наполнен ими по полной.
Плюсы
— не связанность компонентов, мне достаточно просто опубликовать событие, а кого оно интересует не имеет значение.
— не связанность компонентов, я просто подписываюсь на нужные мне события.
— можно добавлять отдельные модули без изменения в существующем функционале.
Минусы
— нужно постоянно описывать новые события и добавлять их в мир.
— нарушение функциональной атомарности.
Последний минус рассмотрим более детально
Представим, что у нас есть объект «ObjectA», в котором вызывается метод «MethodA». Метод «MethodA», состоит из трех шагов и вызывает внутри себя три других метода, которые выполняют эти шаги последовательно («MethodA1», «MethodA2» и «MethodA3»). Во втором методе «MethodA2» происходит публикация какого-то события. И тут происходит следующее: все кто подписан на это событие начнут его обрабатывать, выполняя какую-то свою логику. В этой логике тоже может произойти публикация других событий, обработка которых также может привести к публикации новых событий и так далее. Дерево публикаций и реакции в отдельных случаях может очень сильно разрастись. Такие длинные цепочки крайне тяжело отлаживать.
Но самая страшная проблема, которая тут может произойти, это когда одна из веток цепочки приводит обратно в «ObjectA» и начинает обрабатывать событие путем вызова какого-то другого метода «MethodB». Получается, что метод «MethodA» у нас еще не выполнил все шаги, так как был прерван на втором шаге, и содержит сейчас в себе не валидное состояние (в шаге 1 и 2 мы изменили состояние объекта, но последнее изменение из шага 3 еще не сделали) и при этом начинается выполняться «MethodB» в этом же объекте, имея это не валидное состояние. Такие ситуации порождают ошибки, очень сложно отлавливаются, приводят к тому, что надо контролировать порядок вызова методов и публикации событий, когда по логике этого делать нет необходимости и вводят дополнительную сложность, которую хотелось бы избежать.
Решение
Решить описанную проблему не сложно, достаточно добавить функционал отложенной реакции на событие. В качестве простой реализации такого функционала мы можем завести хранилище, в которое будем складывать произошедшие события. Когда событие произошло, мы не выполняем его немедленно, а просто сохраняем где-то у себя. И в момент наступления очереди выполнения функционала какой-то компоненты в игре (в методе Update, например) мы проверяем на наличие произошедших событий и выполняем обработку, если есть такие события.
Таким образом, при выполнении метода «MethodA» не происходит его прерывание, а опубликованное событие все заинтересованные записывают себе в специальное хранилище. И только после того как к заинтересованным подписчикам дойдет очередь, они достанут из хранилища событие и обработают его. В этот момент весь «MethodA» будет завершен и «ObjectA» будет иметь валидное состояние.
Unity поддерживаете горячую перекомпиляцию скриптов в запущеной игре
Но вроде как есть компании, которые код пишут так, чтобы запущенная в ректоре игра могла пережить перекомпиляцию скриптов. Это очень удобно для быстрой подгонки геймплея.
Но реально ли это в рамках большого проекта?
Дык все ж ссылки на классы херятся при перекомпиляции по-горячему, не?
В готовой игре же нет скриптов как таковых. И зачем вообще перекомпиляция игры?
При отладке в плеере можно на горячую, но все свойства всех объектов должны быть сериализуемые. В полноценной игре, как говорят пацаны, соблюсти эти условия архисложно.
Прикрутите вот это и будет вам счатье http://nlua.org/
Похоже не правильно задал вопрос.
Но вроде как есть компании, которые код пишут так, чтобы запущенная в ректоре игра могла пережить перекомпиляцию скриптов. Это очень удобно для быстрой подгонки геймплея.
Но реально ли это в рамках большого проекта?
FDsagizi
> Но реально ли это в рамках большого проекта?
Не знаю, как на Юнити, но у нас большой проект с игровым кодом на луа и геймплей программисты постоянно используют хот релоад в рантайме для быстрых итераций
FDsagizi
>Но реально ли это в рамках большого проекта?
Всё реально, вопрос только в нужности и потребности этого
Компромиссное решение: не пытаться сделать всю игру сериализируемой, что слишком заморочено, а перед перезагрузкой скриптов делать «quick save», а после ― «quick load».