Unity что такое префаб
Префабы (Prefabs)
Unity’s Prefab system allows you to create, configure, and store a GameObject complete with all its components, property values, and child GameObjects as a reusable Asset. The Prefab Asset acts as a template from which you can create new Prefab instances in the Scene.
When you want to reuse a GameObject configured in a particular way – like a non-player character (NPC), prop or piece of scenery – in multiple places in your Scene, or across multiple Scenes in your Project, you should convert it to a Prefab. This is better than simply copying and pasting the GameObject, because the Prefab system allows you to automatically keep all the copies in sync.
Any edits that you make to a Prefab Asset are automatically reflected in the instances of that Prefab, allowing you to easily make broad changes across your whole Project without having to repeatedly make the same edit to every copy of the Asset.
You can nest Prefabs inside other Prefabs to create complex hierachies of objects that are easy to edit at multiple levels.
However, this does not mean all Prefab instances have to be identical. You can override settings on individual prefab instances if you want some instances of a Prefab to differ from others. You can also create variants of Prefabs which allow you to group a set of overrides together into a meaningful variation of a Prefab.
Some common examples of Prefab use include:
2018–07–31 Page amended with limited editorial review
Префабы (Prefabs)
Unity’s Prefab system allows you to create, configure, and store a GameObject complete with all its components, property values, and child GameObjects as a reusable Asset. The Prefab Asset acts as a template from which you can create new Prefab instances in the Scene.
When you want to reuse a GameObject configured in a particular way – like a non-player character (NPC), prop or piece of scenery – in multiple places in your Scene, or across multiple Scenes in your Project, you should convert it to a Prefab. This is better than simply copying and pasting the GameObject, because the Prefab system allows you to automatically keep all the copies in sync.
Any edits that you make to a Prefab Asset are automatically reflected in the instances of that Prefab, allowing you to easily make broad changes across your whole Project without having to repeatedly make the same edit to every copy of the Asset.
You can nest Prefabs inside other Prefabs to create complex hierachies of objects that are easy to edit at multiple levels.
However, this does not mean all Prefab instances have to be identical. You can override settings on individual prefab instances if you want some instances of a Prefab to differ from others. You can also create variants of Prefabs which allow you to group a set of overrides together into a meaningful variation of a Prefab.
Some common examples of Prefab use include:
2018–07–31 Page amended
Пишем арканоид на Unity. Поведение блоков, префабы и дизайн уровней
Авторизуйтесь
Пишем арканоид на Unity. Поведение блоков, префабы и дизайн уровней
В этой статье мы продолжаем серию уроков о написании простой игры на Unity — классического арканоида. Использовать будем только 2D инструменты, предоставляемые нам движком. В каждой из статей мы затронем один из аспектов написания игры, а в этой настроим поведение игровых блоков и создадим префабы.
Где мы остановились?
В предыдущих двух уроках мы настроили проект, добавили в него ресурсы, а также запрограммировали механику мяча и платформы, находящейся под управлением игрока. Если вы еще не прочитали предыдущие статьи, то мы настоятельно рекомендуем вам это сделать.
Прилагаем список всех уроков:
Превью результата
Ну и по традиции — посмотрим на игру, которая должна получиться у нас по итогам всей серии.
А вот игра, которую мы напишем в этой статье.
Скрипт для блока
На данный момент у нас написана вся базовая механика игры. Не определено только поведение блоков, уничтожая которые игрок получает некоторое количество очков. Блоки — очень важная часть игры. Мы должны создать для них отдельный сценарий, содержащий сведения:
Не забудем и о том, что количество выдерживаемых ударов и заработанные очки могут меняться в зависимости от цвета блока. Исходя из этого, блок должен иметь три переменные:
Первые две переменные будут публичными, чтобы мы могли изменять их значения в редакторе Unity. Третья будет приватной, поскольку предназначена только для внутреннего пользования.
Итак, создадим новый скрипт под название BlockScript, объявим наши переменные и проинициализируем нулем переменную, отвечающую за количество принятых ударов:
Следующим шагом станет определение момента столкновения шарика с блоком. Воспользуемся методом OnCollisionEnter2D, который вызывается каждый раз, когда происходит коллизия.
Для того, чтобы воспользоваться этой функцией, мы должны пометить шар специальным тегом. В редакторе Unity на вкладке Hierarchy выберите мяч, перейдите в окно Inspector и найдите поле Tag. В данный момент объект не имеет тега, а потому в этом поле значится Untagged. Кликните по нему и выберите Add Tag.
После этого откроется новый интерфейс:
В этой статье мы сосредоточимся на свойстве Element 0, которое определят название тега. Свойству Size задайте 2.
Отлично. Теперь заново в окне Inspector кликните по полю Tag и в списке кликните на добавленный нами тег Ball.
Откройте ранее созданный нами скрипт BlockScript. Переопределим метод OnCollisionEnter2D, в котором будем проверять тег объекта, с которым столкнулся наш блок.
Теперь мы можем обнаружить столкновение мяча и блока. При каждой таком коллизии мы будем увеличивать на единицу переменную, отвечающую за количество уже сделанных ударов. Если эта переменная станет равной максимальному количеству ударов, которое выдерживает блок, то мы смело уничтожим этот блок (для этого можно воспользоваться методом Destroy).
Прежде, чем идти дальше, давайте проверим, все ли работает должным образом. В редакторе Unity измените параметр Hits To Kill на 1 и запустите игру. После первого же попадания по блоку, последний должен исчезнуть.
Создание префабов
Мы полностью написали механику блоков. Настало время заполнить наш уровень. Так как для этого мы будем использовать много блоков, то самое время создать префабы.
Префаб — это один из типов ресурсов, предназначений для многократного использования и хранящийся в Project View. Префаб может быть вставлен в любое количество сцен и многократно в одну сцену. Когда префаб добавляется в сцену, создаётся его экземпляр. Все экземпляры являются ссылками на оригинальный префаб и фактически его клонами. Независимо от того, как много экземпляров в проекте, при изменении префаба изменяются соответственно и все его экземпляры.
Преимуществом префаба, как уже сказано выше, является то, что добавив множество экземпляров префаба, можно изменить оригинал единожды, после чего все его экземпляры также будут подвержены этому изменению.
Давайте рассмотрим это на примере. Переименуйте объект Block в Blue Block. Затем создайте новую папку внутри Assets под названием Prefabs. Перетащите Blue Block в новую папку.
Как вы могли заметить, иконка кубика в верхней части вкладки Inspector теперь стала голубенькой, также как и название блока во вкладке Hierarchy. Это значит, что был создан префаб. Довольно просто, не так ли? Отныне, выбрав этот префаб и изменив у него какое-либо значение, обновятся параметры у всех его экземпляров.
Давайте создадим еще один экземпляр префаба: перетащите Blue Block из папки Prefabs во вкладку Hierarchy. Теперь у нас два синих блока, но оба находятся на одной и той же позиции.
Для того, чтобы два блока находились на разных позициях, выберите один из них на вкладке Hierarchy и переместите его на сцене в другое положение. Таким нехитрым образом вы изменили позицию одного конкретного экземпляра, а не всех синих блоков.
Нажмите кнопку Play и проверьте работу игры.
Пересоздание префабов
Давайте создадим префабы и для других блоков: зеленых, желтых и красных. Вот, по какому плану мы должны пойти:
В конце концов мы должны создать четыре различных префаба.
Для того, чтобы игра была более интересной, измените количество ударов для уничтожения блока (параметр Hits To Kill) таким образом:
Добавьте несколько различных блоков на сцену и запустите игру.
Дизайн уровней
Итак, давайте заполним наш уровень. Используя префабы, добавьте требуемое количество различных блоков. Чтобы не засорять проект, создайте во вкладке Hierarchy пустой объект Blocks, а внутри него еще четыре пустых объекта — по одному на каждый цвет. Отсортируйте все существующие блоки по цветам таким образом:
На том этапе игра практически готова, вся игровая механика написана. У вас должно получиться что-то вроде такого:
Набор очков и жизни
Набранные очки и система проверок количества оставшихся жизней делают игру увлекательнее. Но сейчас у нас нет ни того, ни другого. Давайте исправим это!
Откройте PlayerScript, созданный на прошлом уроке, и добавьте две переменные: количество набранных очков и число оставшихся жизней. Игрок будет начинать игру с тремя жизнями и без очков:
У нас должен быть метод, который будет добавлять необходимое количество очков:
Этот метод получает в качестве параметра некоторое количество очков. Но откуда мы будем брать его?
Теперь, когда платформа имеет свой тег, перейдем к сценарию блока BlockScript. Давайте изменим метод OnCollisionEnter2D, в котором найдем нашу платформу при помощи метода FindGameObjectsWithTag и вызовем метод SendMessage, который позволяет выполнить функцию из другого скрипта. Выполнять будем метод addPoints.
Обратим внимание на то, что метод FindGameObjectsWithTag возвращает массив игровых объектов, а т.к. у нас ровно один объект с тегом Player, то 0-ой элемент и будет нашей платформой.
Измените количество очков (параметр Points) в каждом префабе. Например, по такому принципу:
Теперь нам нужно показать в игре количество жизней и набранные очки. Для этого можно воспользоваться методом OnGUI. Обратите на название функции, поскольку оно чувствительно к регистру.
Вернемся в PlayerScript и добавим метод, который будет отнимать количество жизней:
И, наконец, перейдем в BallScript и в момент, когда мячик падает за пределы игрового поля, вызовем метод TakeLife:
На этом все! Запустите игру и проверьте, что все работает правильно.
В следующей части
Вот и закончилась третья часть в нашей серии уроков. Основная механика игры уже готова, поэтому в следующем уроке мы добавим звуковые эффекты и развернем готовую игру.
Создание экземпляров префабов во время работы приложения
Префабы приходятся очень кстати, когда вы хотите создать экземпляры сложных игровых объектов во время игрового процесса. Альтернативой создания экземпляров префабов является создание GameObject с нуля используя код. Создание экземпляра префаба имеет много преимуществ над альтернативным подходом:
Общие сценарии
Чтобы показать мощь префабов, давайте рассмотрим некоторые основные ситуации, где они могут пригодиться:
Построение стены
Это объяснение иллюстрирует преимущества использования префабов над созданием объектов из кода.
В первую очередь, давайте построим стену из кода:
Если вы исполните этот код, вы увидите целую кирпичную стену, создаваемую при входе в режим Play Mode. На отдельный кирпич приходится по 2 строки, отвечающие за функциональность: строки CreatePrimitive() и AddComponent(). Пока что не так и плохо, но все кирпичи не имеют текстур. Каждое дополнительное действие, которое мы хотим сделать с кирпичом, вроде изменения текстуры, трения или массы Rigidbody, требует дополнительную строку.
Если вы создадите префаб и выполните все установки вручную, то вам понадобится использовать лишь по одной строке на создание и установку каждого кирпича. Это освобождает вас от поддержания и изменения тонн кода, когда вы хотите внести изменения. При использовании префаба вы просто вносите изменения в него и жмёте Play. Совсем нет надобности изменять код.
Если вы используете префаб для каждого кирпича, то вот код, который вам понадобится для создания стены.
Он не только очень чистый, но им можно пользоваться много раз. В нём не упоминается ни создание куба, ни то, что он должен содержать Rigidbody. Всё это задано в префабе, который может быть быстро создан в редакторе
Теперь нам остаётся лишь создать префаб, который мы делаем в редакторе. Вот так:
We’ve created our Brick Prefab, so now we have to attach it to the brick variable in our script. When you select the empty GameObject that contains the script, the Brick variable will be visible in the inspector.
Теперь перетащите префаб “Brick” из окна Project View на переменную brick в инспекторе. Нажмите Play и вы увидите стену построенную из префабов.
Этот шаблон рабочего процесса можно использовать и использовать в Unity. В начале вы, возможно, будете интересоваться, почему же это лучше, чем создание куба из кода, который длиннее лишь на две строки.
Но т.к. вы сейчас используете префаб, вы можете настроить Prefab за секунды. Хотите внести изменения для всей кучи образцов? Настройте Rigidbody в префабе всего один раз. Хотите использовать иной Material для всех образцов? Перетащите материал на префаб всего один раз. Хотите изменить трение? Используйте другой физический материал (Physic Material) в коллайдере префаба. Хотите добавить системы частиц ко всем кирпичам? Добавьте дочернюю систему к префабу всего один раз.
Создание экземпляров ракет и взрывов
Вот как префабы подходят для данного сценария:
В то время как можно собрать объект ракеты полностью из кода, вручную добавляя компоненты и устанавливая свойства, было бы гораздо проще просто создать экземпляр префаба. Вы можете создать экземпляр ракеты просто одной строкой кода, не важно, насколько сложным будет префаб ракеты. После создания экземпляра префаба, вы также можете изменить любые свойства созданного экземпляра объекта (например, вы можете установить скорость Rigidbody ракеты).
Этот скрипт покажет, как запустить ракету используя функцию Instantiate().
Замена персонажа на Ragdoll или обломки
Допустим у вас есть вражеский персонаж с ригом и он умирает. Вы можете просто проиграть анимацию смерти и отключить все скрипты, которые обычно отвечают за логику врага. Вам, скорее всего, придётся позаботиться об удалении нескольких скриптов, добавлении некоторой дополнительной логики, чтобы убедиться, что никто не будет атаковать уже мёртвого врага, и о других задачах очистки.
Гораздо лучше будет подход, включающий мгновенное удаление всего персонажа, и замена его созданным экземпляром префаба обломков. Это даёт вам больше возможностей. Вы можете использовать другой материал для мёртвого персонажа, присоединить совершенно другие скрипты, создать экземпляр префаба содержащий объект сломанный на много кусков, чтобы симулировать разбившегося врага, или просто создать экземпляр префаба, содержащий определённую версию персонажа.
Любой из этих вариантов может быть достигнут разовым вызовом Instantiate(). Вам надо просто привязать к нему правильный префаб и всё готово!
Это стандартные шаги, если надо собрать префаб сломанного самолёта:
Следующий пример покажет, как эти шаги моделируются в коде.
Размещение группы объектов по заданному шаблону
Допустим вы хотите поместить группу объектов по сетке или кругу. Как всегда, это может быть выполнено двумя способами:
Так используйте вместо этого Instantiate() с префабом! Мы думаем, что вы уже поняли нашу идею, почему префабы так удобны в этих случаях. Вот необходимый для этих сценариев код:
Префабы (Prefabs)
Довольно удобно работать с GameObject в сцене, добавляя компоненты и изменяя их значения на нужные вам в инспекторе. Однако, это может создать ряд проблем в таких случаях, когда вы работаете над созданием NPC, объектом или предметом, который многократно встречается в сцене. Вы, конечно, можете просто скопировать эти объекты для создания дубликатов, но все они будут редактироваться независимо друг от друга. Обычно вы желаете, чтобы все экземпляры отдельно взятого объекта имели одинаковые значения свойств, чтобы при редактировании одного такого объекта в сцене вам не пришлось повторно вносить те же изменения и во все остальные копии.
Fortunately, Unity has a Prefab asset type that allows you to store a GameObject object complete with components and properties. The prefab acts as a template from which you can create new object instances in the scene. Any edits made to a prefab asset are immediately reflected in all instances produced from it but you can also override components and settings for each instance individually.
Использование префабов
Вы можете создать префаб, выбрав Asset > Create Prefab и перетащив объект со сцены в “пустой” префаб, появившийся в проекте. После чего можно создавать экземпляры префаба просто перетаскивая его из окна Project на сцену. Имена объектов-экземпляров префабы, будут подсвечиваться синим в окне Hierarchy (имена обычных объектов имеют чёрный цвет).
Как уже упоминалось выше, изменения в префабе автоматически применятся ко всем её экземплярам, однако вы можете изменять и отдельные экземпляры. Это полезно например в случае, когда вы желаете создать несколько похожих NPC, но с внешними различиями, чтобы добавить реалистичности. Чтобы было чётко видно, что свойство в экземпляре префаба изменено, оно показывается в инспекторе жирным шрифтом (если к экземпляру префаба добавлен совершенно новый компонент, то все его свойства будут написаны жирным шрифтом).
Mesh Renderer на экземпляре префаба с переопределённым свойством “Cast Shadows”
Также, вы можете создавать экземпляры префабов из кода во время выполнения приложения. Прочтите страницу руководства про создание экземпляров префабов для дополнительной информации.
Редактирование префаба из его экземпляров
Инспектор экземпляра префаба содержит три кнопки, которые у обычных объектов отсутствуют: Select (Выделить), Revert (Отменить) и Apply (Применить).
The Select button selects the prefab asset from which the instance was generated. This allows you to edit the main prefab and thereby change all its instances. However, you can also save overridden values from an instance back to the originating prefab using the Apply button (modified Transform position values are excluded for obvious reasons). This effectively lets you edit all instances (except those which override the value changed) via any single instance and is a very quick and convenient way to make global changes. If you experiment with overriding properties but then decide you preferred the default values, you can use the Revert button to realign the instance with its prefab.