Будем делать индикатор здоровья персонажа или как еще говорят, полоска здоровья. В общем, главный приоритет для нас, это удобство использования и настройки. Это улучшенный вариант бара, который мы публиковали ранее. Кроме всего прочего, рассмотрим, как быстро настроить стандартный слайдер, буквально за пару минут, для нашего индикатора. Основные возможности скрипта: установка уровня здоровья, от нуля и до нужного значения; регулировка ширины бара, относительно разрешения экрана; возможность размещать индикатор как слева, так и справа; быстрый доступ к текущему значению и функции изменения значения здоровья, из любого другого скрипта.
Преступим, первым делом добавим слайдер и настроим его, GameObject > UI > Slider:
И выключаем у него интерактивность, для того, чтобы невозможно было взаимодействовать со слайдером, например, мышкой.
В слайдере удаляем объект Background и выбираем Fill Area, настраиваем как на криншоте:
Тут же, находим объект Fill и настраиваем так же.
Далее, берем Handle Slide Area и делаем тоже самое, что и с предыдущим объектом. Последний штрих, находим Handle, ставим ширину на единицу, а альфа канал изображения на ноль, в общем как показано ниже:
Вот и всё. Полоска здоровья нашего персонажа готова, разместите слайдер в нужной части экрана и двигаемся дальше.
Создаем C# скрипт HealthBar, цепляем его на пустой объект например:
В переменной slider указываем ранее созданный слайдер здоровья, если индикатор с правой стороны экрана, то обязательно ставим галочку isRight. Ширина width, чем больше значение, там меньше будет размер полоски, так как разрешение экрана по ширине тут, делится на данное значение.
Источник
Юнити как сделать здоровье
ollkill 09 фев 2013, 02:08
Как только запустите значение вашего хп начнет снижаться до тех пор, пока не станет равно 0, это из-за того что есть функция FixedUpdate(). Когда вы убедились что все работает достойно, сносите ее нафиг и пользуетесь.
using UnityEngine ; using System.Collections ;
public class HealsBar : MonoBehaviour <
public float maxHeals ; public Texture HealsTexture ;
Ты прочти внимательнее «Для нубов)», если ты это можешь сделать — прекрасно, но ведь не все кто открыли юню сразу великие программисты.
А теперь подробнее, у меня покамисть этот код стоит, для удобного мониторинга что происходит и все ок. Ты как вызываешь и что, скинь код вызова
Re: Полоска жизни для нубов. Бери и используй
koly4iu 20 фев 2013, 15:34
Re: Полоска жизни для нубов. Бери и используй
koly4iu 20 фев 2013, 16:00
Re: Полоска жизни для нубов. Бери и используй
ollkill 20 фев 2013, 16:15
Источник
Система здоровья
Помощь в написании контрольных, курсовых и дипломных работ здесь.
Unity система здоровья Пытаюсь построить систему здоровья через on collision 2d или on Trigger 2d. Как можно проверить в.
Не работает код (Восстановление здоровья и временное бессмертие в 2D игре) Доброго времени суток. После того, как я добавил в код все необходимое для работы гема.
Индикатор здоровья Проблема заключаеться в следующем: Решил создать игру 5ти минутку ) ну так просто чтобы навык.
Ногти — зеркало здоровья. Обсуждаем здесь состояние своих ногтей а также недуги, на которые указывают изменение цвета, формы.
Записывайтесь на профессиональные IT-курсы здесь
Обучайтесь IT-профессиям с гарантией трудоустройства здесь.
Индикатор здоровья персонажа Как сделать индикатор здоровья персонажа?думаю,либо в процентном составе либо полоску.ну,попробую в.
Тест по оценке здоровья на Java Здравствуйте, форумчане)) В работе с Java я абсолютный новичок, поэтому найти ошибки таки не.
Вред Wi-Fi для здоровья людей Несмотря на то что современные портативные компьютеры и мобильные устройства с wi-fi пользуются.
Феминизм вреден для здоровья С тех пор как Мэри Уолстонкрафт написала свое эссе «Защита прав женщины» в 1792 году, ее активные.
BMI калькулятор с индикатором здоровья Проблема состоит в том, что бы результат BMI калькулятора выводился на индикатор, который поделен.
Подозрительность в оценке состояния здоровья Как называется отклонение, когда человек часто паникует, подозревая у себя разные болячки, без.
Или воспользуйтесь поиском по форуму:
Изучайте английский язык в крупнейшей европейской школе Skyeng
Источник
Как сделать каждому игроку полоску жизней
Помощь в написании контрольных, курсовых и дипломных работ здесь.
Как сделать счётчик жизней и вывести его? Доброго времени суток друзья! Нужна ваша помощь! Мне нужно сделать счётчик жизней, допустим «Health.
Как сделать враждебную стрельбу по игроку в 2D Помогите, я начинающий игродел хотел сделать босса на 2д платформере что бы он в меня стрелял и я.
Сделать полоску с телефонами, как на скриншоте Уважаемые форумчане.помогите с такой вот бедой)хочу сделать полоску как на картинке(картинка.
Как сделать полоску сбора денег? Мне нужно сделать полоску сбора денег по похожему примеру https://chance.su/ Подскажите.
Записывайтесь на профессиональные IT-курсы здесь
хы.. тут задача не очень короткая. все зависит от вашего кода. но описывать тут довольно много нужно, посмотрите видео
оно научит прикреплять к объекту любой UI объект, lootAt можно назначать из скрипта.
Добавлено через 3 минуты
а, разрешение запроси , зарегистируйся там и запрос сделай
у тебя очень много find и GetComponent в коде, избавляйся максимально от них, они жрут безбожно. посмотри понятие пул, у меня когда скачаешь проект в скрипте player он как раз реализован для стрельбы пуль.
Комментарий модератора
OKLINS, Seleborn, Устное предупреждение обоим. Правила форума, пункт 4.6
Обучайтесь IT-профессиям с гарантией трудоустройства здесь.
Как сделать макрос на игру Эстафета (Передача очереди следующему игроку) Здравствуйте. Хелп. Кто может и есть время на вот такое. Есть игра обозначение которой.
Как сделать полоску ввода (Enter) всегда не пустой? Как сделать полоску ввода (Enter) всегда не пустой(Смотрите фото)? Проблема в том, что если я нажму.
Сделать отнимание жизней, если машина соприкасается с препятствиями Нужно придумать какое то условие для проигрыша. Не особо пойму как мне определять когда машина.
Как сделать вот такую полоску, которая заходит за блок, далее внутри Вот пример: Картинка.
Нужно сделать такой фон (Полоску фона (адаптивного) как на Рамблере про олимпиаду) Привет. Нужно сделать такую полоску фона (адаптивного) как на Рамблере про олимпиаду.
Или воспользуйтесь поиском по форуму:
Изучайте английский язык в крупнейшей европейской школе Skyeng
Источник
Unity: отрисовываем множество полосок здоровья за один drawcall
Недавно мне нужно было решить задачу, достаточно распространённую во многих играх с видом сверху: рендерить на экране целую кучу полосок здоровья врагов. Примерно вот так:
Очевидно, что я хотел сделать это как можно эффективнее, желательно за один вызов отрисовки. Как обычно, прежде чем приступать к работе, я провёл небольшое онлайн-исследование решений других людей, и результаты были очень разными.
Я не буду никого стыдить за код, но достаточно сказать, что некоторые из решений были не совсем блестящими, например, кто-то добавлял к каждому врагу объект Canvas (что очень неэффективно).
Метод, к которому я в результате пришёл, немного отличается от всего того, что я видел у других, и не использует вообще никаких классов UI (в том числе и Canvas), поэтому я решил задокументировать его для общества. А для тех, кто хочет изучить исходный код, я выложил его на Github.
Почему бы не использовать Canvas?
По одному Canvas для каждого врага — это очевидно плохое решение, но я мог использовать общий Canvas для всех врагов; единственный Canvas тоже бы привёл к батчингу вызовов отрисовки.
Однако мне не нравится связанный с таким подходом объём выполняемой в каждом кадре работы. Если вы используете Canvas, то в каждом кадре придётся выполнять следующие операции:
Определять, какие из врагов находятся на экране, и выделять каждому из них из пула полоску UI.
Проецировать позицию врага в камеру, чтобы расположить полоску.
Изменять размер «заливки» части полоски, вероятно, как Image.
Скорее всего изменять размер полосок в соответствии с типом врагов; например, у крупных врагов должны быть большие полоски, чтобы это не выглядело глупо.
Как бы то ни было, всё это загрязняло бы буферы геометрии Canvas и приводило к перестройке всех данных вершин в процессоре. Я не хотел, чтобы всё это выполнялось для столь простого элемента.
Вкратце о моём решении
Краткое описание процесса моей работы:
Прикрепляем объекты полосок энергии к врагам в 3D.
Это позволяет автоматически располагать и усекать полоски.
Позицию/размер полоски можно настраивать в соответствии с типом врага.
Полоски мы направим на камеру в коде с помощью transform, который всё равно есть.
Шейдер гарантирует, что они всегда будут рендериться поверх всего.
Используем Instancing для рендеринга всех полосок за один вызов отрисовки.
Используем простые процедурные UV-координаты для отображения уровня заполненности полоски.
А теперь давайте рассмотрим решение подробнее.
Что такое Instancing?
В работе с графикой уже давно используется стандартная техника: несколько объектов объединяются вместе, чтобы они имели общие данные вершин и материалы и их можно было отрендерить за один вызов отрисовки. Нам нужно именно это, потому что каждый вызов отрисовки — это дополнительная нагрузка на ЦП и GPU. Вместо выполнения по одному вызову отрисовки на каждый объект мы рендерим их все одновременно и используем шейдер для добавления вариативности в каждую копию.
Можно делать это вручную, дублируя данные вершин меша X раз в одном буфере, где X — максимальное количество копий, которое может быть отрендерено, а затем использовав массив параметров шейдера для преобразования/окраски/варьирования каждой копии. Каждая копия должна хранить знание о том, каким нумерованным экземпляром она является, чтобы использовать это значение как индекс массива. Затем мы можем использовать индексированный вызов рендера, который приказывает «рендерить только до N», где N — это число экземпляров, которое на самом деле нужно в текущем кадре, меньшее, чем максимальное количество X.
В большинстве современных API код для этого уже есть, поэтому вручную это делать не требуется. Эта операция называется «Instancing»; по сути, она автоматизирует описанный выше процесс с заранее заданными ограничениями.
Движок Unity тоже поддерживает instancing, в нём есть собственный API и набор макросов шейдеров, помогающие в его реализации. Он использует определённые допущения, например, о том, что в каждом экземпляре требуется полное 3D-преобразование. Строго говоря, для 2D-полосок оно нужно не полностью — мы можем обойтись упрощениями, но поскольку они есть, мы будем использовать их. Это упростит наш шейдер, а также обеспечит возможность использования 3D-индикаторов, например, кругов или дуг.
Класс Damageable
У наших врагов будет компонент под названием Damageable , дающий им здоровье и позволяющий им получать урон от коллизий. В нашем примере он довольно прост:
Объект HealthBar: позиция/поворот
Объект полосы здоровья очень прост: по сути, это всего лишь прикреплённый к врагу Quad.
Мы используем scale этого объекта, чтобы сделать полоску длинной и тонкой, и разместим её прямо над врагом. Не беспокойтесь о её повороте, мы исправим его с помощью кода, прикреплённого к объекту в HealthBar.cs :
Этот код всегда направляет quad в сторону камеры. Мы можем выполнять изменение размера и поворота в шейдере, но я реализую их здесь по двум причинам.
Во-первых, instancing в Unity всегда использует полный transform каждого объекта, и поскольку мы всё равно передаём все данные, можно их и использовать. Во-вторых, задание масштаба/поворота здесь гарантирует, что ограничивающий параллелограмм для усечения полоски всегда будет верным. Если бы мы сделали задание размера и поворота обязанностью шейдера, то Unity мог бы усекать полоски, которые должны быть видимы, когда они находятся близко к краям экрана, потому что размер и поворот их ограничивающего параллелограмма не будут соответствовать тому, что мы собираемся рендерить. Разумеетсяя, мы могли бы реализовать свой собственный способ усечения, но обычно при возможности лучше использовать то, что у нас есть (код Unity является нативным и имеет доступ к большему количеству пространственных данных, чем мы).
Я объясню, как рендерится полоска, после того, как мы рассмотрим шейдер.
Шейдер HealthBar
В этой версии мы создадим простую классическую красно-зелёную полоску.
Я используют текстуру размером 2×1, с одним зелёным пикселем слева и одним красным справа. Естественно, я отключил mipmapping, фильтрацию и сжатие, а для параметра addressing mode задал значение Clamp — это значит, что пиксели нашей полоски всегда будут идеально зелёными или красными, а не растекутся по краям. Это позволит нам изменять в шейдере координаты текстуры для сдвига линии, разделяющей красный и зелёный пиксели вниз и вверх по полоске.
(Так как здесь всего два цвета, я мог просто использовать в шейдере функцию step для возврата в точке одного или другого. Однако в этом методе удобно то, что при желании можно использовать более сложную текстуру, и это будет работать аналогично, пока переход находится в середине текстуры.)
Для начала мы объявим необходимые нам свойства:
_MainTex — это красно-зелёная текстура, а _Fill — значение от 0 до 1, где 1 — это полное здоровье.
Далее нам нужно приказать полоске рендериться в очереди overlay, а значит, игнорировать всю глубину в сцене и рендериться поверх всего:
Следующая часть — это сам код шейдера. Мы пишем шейдер без освещения (unlit), поэтому нам не нужно беспокоиться об интеграции с различными моделями поверхностных шейдеров Unity, это простая пара вершинного/фрагментного шейдеров. Для начала напишем бутстреппинг:
По большей мере это стандартный bootstrap, за исключением #pragma multi_compile_instancing , которая сообщает компилятору Unity, что нужно компилировать для Instancing.
Вершинная структура должна включать в себя данные экземпляров, поэтому мы сделаем следующее:
Также нам нужно задать, что именно будет находиться в данных экземляров, кроме того, что за нас обрабатывает Unity (transform):
Так мы сообщаем, что Unity должен создать буфер под названием «Props» для хранения данных каждого экземпляра, и внутри него мы будем использовать по одному float на экземпляр для свойства под названием _Fill .
Можно использовать и несколько буферов; это стоит делать, если у вас есть несколько свойств, обновляемых с разной частотой; разделив их, можно, например, не менять один буфер при изменении другого, что более эффективно. Но нам этого не требуется.
Наш вершинный шейдер почти полностью выполняет стандартную работу, потому что размер, позиция и поворот и так передаются в transform. Это реализуется с помощью UnityObjectToClipPos , который автоматически использует transform каждого экземпляра. Можно представить, что без instancing это обычно было бы простым использованием одного матричного свойства. но при использовании instancing внутри движка это выглядит как массив матриц, и Unity самостоятельно выбирает матрицу, подходящую к данному экземпляру.
Также нем нужно изменять UV, чтобы менять расположение точки перехода из красного в зелёный в соответствии со свойством _Fill . Вот соответствующий фрагмент кода:
UNITY_SETUP_INSTANCE_ID и UNITY_ACCESS_INSTANCED_PROP выполняют всю магию, осуществляя доступ к нужной версии свойства _Fill из буфера констант для этого экземпляра.
Мы знаем, что в обычном состоянии UV-координаты четырёхугольника (quad) покрывают весь интервал текстуры, и что разделительная линия полоски находится посередине текстуры по горизонтали. Поэтому небольшие математические расчёты по горизонтали сдвигают полоску влево или вправо, а значение Clamp текстуры обеспечивают заполнение оставшейся части.
Фрагментный шейдер не мог быть проще, потому что вся работа уже выполнена:
Полный код шейдера с комментариями доступен в репозитории GitHub.
Материал Healthbar
Дальше всё просто — нам всего лишь нужно назначить нашей полоске материал, который использует этот шейдер. Больше почти ничего делать не нужно, достаточно только выбрать нужный шейдер в верхней части, назначить красно-зелёную текстуру, и, что самое важное, поставить флажок «Enable GPU Instancing».
Обновление свойства HealthBar Fill
Итак, у нас есть объект полоски здоровья, шейдер и материал, который нужно рендерить, теперь нужно задать для каждого экземпляра свойство _Fill . Мы делаем это внутри HealthBar.cs следующим образом:
Мы превращаем CurrentHealth класса Damageable в значение от 0 до 1, разделив его на MaxHealth . Затем мы передаём его свойству _Fill с помощью MaterialPropertyBlock .
Если вы ещё не использовали MaterialPropertyBlock для передачи данных в шейдеры, даже без instancing, то вам нужно изучить его. Он не так хорошо объяснён в документации Unity, но является самым эффективным способом передачи данных каждого объекта в шейдеры.
В нашем случае, когда используется instancing, значения для всех полосок здоровья упаковываются в буфер констант, чтобы их можно было передать их все вместе и отрисовать за один раз.
Здесь нет почти ничего, кроме бойлерплейта для задания переменных, и код довольно скучный; подробности см. в репозитории GitHub.
В репозитории GitHub есть тестовое демо, в котором куча злых синих кубиков уничтожается героическими красными сферами (ура!), получая урон, отображаемый описанными в статье полосками. Демо написано в Unity 2018.3.6f1.
Эффект от использования instancing можно наблюдать двумя способами:
Панель Stats
Нажав Play, щёлкните на кнопку Stats над панелью Game. Здесь вы можете увидеть, сколько вызовов отрисовки экономится благодаря instancing (батчингу):
Запустив игру, вы можете нажать на материал HealthBar и снять флажок с «Enable GPU Instancing», после чего число сэкономленных вызовов снизится до нуля.
Отладчик кадров
Запустив игру, перейдите в меню Window > Analysis > Frame Debugger, а затем нажмите в появившемся окне «Enable».
Слева внизу вы увидите все выполняемые операции рендеринга. Заметьте, что пока там есть множество отдельных вызовов для врагов и снарядов (при желании можно реализовать instancing и для них). Если прокрутить до самого низа, то вы увидите пункт «Draw Mesh (instanced) Healthbar».
Этот единственный вызов рендерит все полоски. Если нажать на эту операцию, а затем на операцию над ней, то вы увидите, что все полоски исчезнут, потому что они отрисовываются за один вызов. Если находясь во Frame Debugger, вы снимете у материала флажок «Enable GPU Instancing», то увидите, что одна строка превратилась в несколько, а после установки флажка — снова в одну.