Здоровье персонажа / Health Bar
Будем делать индикатор здоровья персонажа или как еще говорят, полоска здоровья. В общем, главный приоритет для нас, это удобство использования и настройки. Это улучшенный вариант бара, который мы публиковали ранее. Кроме всего прочего, рассмотрим, как быстро настроить стандартный слайдер, буквально за пару минут, для нашего индикатора. Основные возможности скрипта: установка уровня здоровья, от нуля и до нужного значения; регулировка ширины бара, относительно разрешения экрана; возможность размещать индикатор как слева, так и справа; быстрый доступ к текущему значению и функции изменения значения здоровья, из любого другого скрипта.
Преступим, первым делом добавим слайдер и настроим его, GameObject > UI > Slider:
И выключаем у него интерактивность, для того, чтобы невозможно было взаимодействовать со слайдером, например, мышкой.
В слайдере удаляем объект Background и выбираем Fill Area, настраиваем как на криншоте:
Тут же, находим объект Fill и настраиваем так же.
Далее, берем Handle Slide Area и делаем тоже самое, что и с предыдущим объектом. Последний штрих, находим Handle, ставим ширину на единицу, а альфа канал изображения на ноль, в общем как показано ниже:
Вот и всё. Полоска здоровья нашего персонажа готова, разместите слайдер в нужной части экрана и двигаемся дальше.
Создаем C# скрипт HealthBar, цепляем его на пустой объект например:
using UnityEngine; using UnityEngine.UI; using System.Collections; public class HealthBar : MonoBehaviour < public float maxValue = 100; public Color color = Color.red; public int width = 4; public Slider slider; public bool isRight; private static float current; void Start() < slider.fillRect.GetComponent().color = color; slider.maxValue = maxValue; slider.minValue = 0; current = maxValue; UpdateUI(); > public static float currentValue < get < return current; >> void Update () < if(current < 0) current = 0; if(current >maxValue) current = maxValue; slider.value = current; > void UpdateUI() < RectTransform rect = slider.GetComponent(); int rectDeltaX = Screen.width/width; float rectPosX = 0; if(isRight) < rectPosX = rect.position.x - (rectDeltaX - rect.sizeDelta.x)/2; slider.direction = Slider.Direction.RightToLeft; >else < rectPosX = rect.position.x + (rectDeltaX - rect.sizeDelta.x)/2; slider.direction = Slider.Direction.LeftToRight; >rect.sizeDelta = new Vector2(rectDeltaX, rect.sizeDelta.y); rect.position = new Vector3(rectPosX, rect.position.y, rect.position.z); > public static void AdjustCurrentValue(float adjust) < current += adjust; >>
В переменной slider указываем ранее созданный слайдер здоровья, если индикатор с правой стороны экрана, то обязательно ставим галочку isRight. Ширина width, чем больше значение, там меньше будет размер полоски, так как разрешение экрана по ширине тут, делится на данное значение.
Доступ из других скриптов:
// добавить здоровья HealthBar.AdjustCurrentValue(10); // убавить здоровье HealthBar.AdjustCurrentValue(-10); // получить текущее значение Debug.Log("Здоровье персонажа на данный момент:" + HealthBar.currentValue);
Скачать демо проект по теме:
Как сделать, чтобы при нажатии на персонажа в юнити он говорил фразу [дубликат]
Пожалуйста, уточните вашу конкретную проблему или приведите более подробную информацию о том, что именно вам нужно. В текущем виде сложно понять, что именно вы спрашиваете.
31 янв в 15:27
Начни с прочтения книг по основам юнити. А просто включить юнити и сидеть в надежде, что придёт озарение — это так себе подход
31 янв в 15:32
Я читал много про основы юнити и тщательного разбирался, но именно ответа на мой вопрос я нигде не нашёл
31 янв в 15:37
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
если это для 3D объекта , тогда можно создать луч , Raycast , из камеры в точку нажатия , проверить если луч попал в игрока, тогда можно вызвать метод воспроизводящий mp-3 файл , или иной поддерживаемый формат.
using UnityEngine; public class ClickSound : MonoBehaviour < public AudioClip clickSound; private void Update() < if (Input.GetMouseButtonDown(0)) < Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hit; if (Physics.Raycast(ray, out hit)) < if (hit.collider != null && hit.collider.gameObject.name == "Player") < PlayClickSound(); >> > > private void PlayClickSound() < if (clickSound != null) < AudioSource audioSource = GetComponent(); if (audioSource == null) < audioSource = gameObject.AddComponent(); > audioSource.PlayOneShot(clickSound); > > >
1.В поле с audioSource перетащите требуемый файл 2.Нужно повесить данный скрипт на игрока , у которого должен быть добавлен компонент MeshColider или какой либо другой колайдер + компонент AudioSource. 3.Поменять имя игрока в скрипте на действительное
Передвижение персонажа в 2D платформере
Я пытаюсь сделать хороший скрипт для передвижения персонажа в 2D платформере. Вот, что я понял (кому лень читать, выбранный мной вариант находится под номером 4):
1)Можно сделать его через transform.translate, но это будет достаточно убого. Мы сможем входить в объекты, после чего физика будет пересчитываться и нас будет выталкивать обратно. Короче, подходит этот метод только для перемещения каких-нибудь облаков, с которыми нельзя взаимодействовать или типа того.
2)Можно сделать его через rigidbody2d.addforce, но для платформера это не очень подходит. С одной стороны мы теперь не будем долбиться башкой об стену, но зато мы сможем разгоняться до слишком больших скоростей. Можно это дело немного исправить установкой положительного Linear Drag, тем самым ограничив максимальную скорость. Тем не менее, персонаж будет именно разгоняться до этой скорости, а не набирать её мгновенно, на классическое управление не очень похоже.
3)Можно сделать его через rigidbody2d.moveposition, я делал что-то типа этого:
1 2 3 4
var positionDelta = new Vector2(Input.GetAxisRaw("Horizontal"), 0) * speed * Time.deltaTime; playerRigidBody.MovePosition( playerRigidBody.position + positionDelta );
При таком подходе персонаж будет медленно падать, так как он будет стараться сдвинуться в предыдущую координату Y. Не подходит.
4)И, наконец, вариант, который был близок к идеальному (находится в FixedUpdate):
float movingDirection = Input.GetAxisRaw("Horizontal"); playerRigidBody.velocity = new Vector2(movingDirection * speed, playerRigidBody.velocity.y);
Вот всё хорошо, но возникает проблема: двигается персонаж как-то дёргано. Причём касается это любого передвижения через rigidbody.
Вот, что я заметил:
1)Если сделать передвижение через transform.translate в методе Update, то персонаж двигается плавно. Если перенести его в FiexedUpdate(), то двигается он уже дёргано. Если перенести передвижение из 4-го примера в Update из FixedUpdate, то проблема не уходит. Если перенести в LateUpdate(), то тоже не уходит.
2)Я так понял, что проблема состоит в отсутствии синхронизации между частотой кадров и частотой расчёта физики. У меня монитор на 60 Гц, следовательно период его обновления равен 1/60 = 0,0166666. Я выставил значение Fixed Timestep на такое и. проблема, можно сказать, решилась. Ну, по крайней мере стало гораздо лучше. Если значение округлить, допустим, до 0,017, то прям заметно, что стало хуже.
Можно ли решить мою проблему без изменения Fixed Timestep (и без ограничения количества кадров таким образом, чтобы периоды обновления совпали)? Это сейчас у меня рендерит 60 кадров в секунду, а если будет рендерить 40? Или если купить монитор на 120 Гц? Проблема снова вернётся.
Вполне может оказаться, что проблема была в чём-то другом и мои догадки отношения к проблеме не имеют.
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:
Смерть персонажа в 2d платформере
При смерти персонажа игроку дают 2 кнопки. При нажатии на первую кнопку персонаж должен возродиться.
Как сделать смерть персонажа в 2D платформере?
В моём платформере есть отдельно канвас с панелью жизней. Всё работает хорошо, сердечки уменьшаются.
Ищу человека для разработки физики персонажа в 2д платформере
Здравствуйте! Долго делаю проект и уходит надежда закончить его. Трудно признать, но моих знаний не.
Передвижение персонажа
Доброго времени суток Есть передвижение персонажа и вращение при помощи мыши но возникла проблема.
Передвижение персонажа
Всем здравствуйте! У меня возникла проблема с передвижением персонажа. Я в интернете много искала.
891 / 161 / 84
Регистрация: 30.07.2022
Сообщений: 1,389
Записей в блоге: 4
Ostaev,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
using UnityEngine; namespace student.ierecumi { [RequireComponent(typeof(Animator))] [RequireComponent(typeof(Rigidbody2D))] public class Hero1 : MonoBehaviour { [SerializeField] private float _speed = 3.0f; [SerializeField] private float _jumpHeight = 1.0f; [SerializeField] private LayerMask _groundLayer; [Space] [SerializeField] private float _groundChecRadius; [SerializeField] private Vector3 _groundChecPositionDelta; [Space] [SerializeField] private bool _isGizmos = true; private Rigidbody2D _rigidbody2D; private float _direction; private SpriteRenderer _sprite; private void Awake() { _rigidbody2D = GetComponentRigidbody2D>(); _sprite = GetComponentSpriteRenderer>(); } void Update() { _direction = Input.GetAxis("Horizontal"); if (_isGizmos) _sprite.color = IsGrounded() ? Color.green : Color.red; _sprite.flipX = _direction 0 ? true : false; if (Input.GetKeyDown(KeyCode.Space) && IsGrounded()) Jump(); } private void FixedUpdate() { _rigidbody2D.velocity = new Vector2(_direction * _speed, _rigidbody2D.velocity.y); } public void Jump() { float jumpForce = Mathf.Sqrt(_jumpHeight * -2 * (Physics2D.gravity.y * _rigidbody2D.gravityScale)); if (IsGrounded()) _rigidbody2D.AddForce(new Vector2(0, jumpForce), ForceMode2D.Impulse); } private bool IsGrounded() { var hit = Physics2D.CircleCast(transform.position + _groundChecPositionDelta, _groundChecRadius, Vector2.down, 0, _groundLayer); return hit.collider != null; } private void OnDrawGizmos() { if (_isGizmos) { Gizmos.color = IsGrounded() ? Color.green : Color.red; Gizmos.DrawSphere(transform.position + _groundChecPositionDelta, _groundChecRadius); } } } }
Как сделать прыжок на Unity 3D
Всем добра! Рад видеть на этой странице) Сегодня, я попытаюсь объяснить, каким образом можно реализовать прыжок в Unity 3D, которую все мы так любим. Делать мы это будем на примере 2D проекта, однако для 3D мало что будет отличаться.
Итак, для начала определимся с тем что у нас будет в итоге. Персонаж будет работать по физике, то-есть на нем будет компонент RigidBody2D. Прыжок будем делать одиночный, если вам нужен двойной прыжок, можно будет разобрать его в следующей статье. Собственно больше ни чего не будет, дабы не отвлекаться ни на что кроме прыжка.
Настройка сцены для прыжков
Думаю наш 2D персонаж будет выглядеть сегодня как то так.
Хм, персонаж есть, нужна поверхность по которой он будет прыгать. Да, ходить в этом уроке мы его учить не будем, и так сойдет, как говориться) Однако, это не сложно, и если кому то интересно, то можно написать статью и на эту тему.
Вроде-бы выглядит не плохо. Но если сейчас запустить игру то ни чего не будет происходить. Нужно ведь развесить коллайдеры и риджидбоди. Сделаем это.
На персонажа нужно повесить компонент RidgidBody2D и, к примеру, BoxCollider2d. А на землю только BoxCollider2D.
Земле нужно дать ТЕГ «ground», что-бы отличать от чего мы прыгаем.
Ну вот, теперь если запустить игру, то все так-же ничего не произойдет, но теперь объекты на сцене подвержены физике.
Отлично! Теперь разберем алгоритм прыжка.
Если ( персонаж на земле и нажат пробел)
то прыгаем.
Иначе игнорируем пробел
Все просто, ни так ли? Но как определить на земле-ли персонаж, спросите вы?
Для этого нужно добавить на персонажа триггер, который будет реагировать на землю и сообщать нам, что мы приземлились.
Добавим на игрока еще один коллайдер и поставим галочку isTrigger. И перейдем, пожалуй, к скрипту.
Скрипт
В Unity прыжок можно сделать так. Даем игроку пинок вверх и он летит! Если быть точнее, то в определенный момент нужно приложить к игроку вертикальную силу с типом Impuls. Далее будет скрипт с пояснениями. Создаем скрипт C# и бросаем его на игрока.
using System.Collections; using System.Collections.Generic; using UnityEngine; public class jump : MonoBehaviour < bool is_ground = false; //переменная которая хранит в себе значение, "на земле ли игрок" Rigidbody2D player; //так как мы часть обращаемся к физике, то не лишним будет закэшировать этот компонент public float force = 6; //сила с которой будет прыгать персонаж void Start() < player = GetComponent(); //при старке сцены, получаем компонент и сохраняем в переменную > void OnTriggerStay2D(Collider2D col) < //если в тригере что то есть и у обьекта тег "ground" if (col.tag == "ground") is_ground = true; //то включаем переменную "на земле" >void OnTriggerExit2D(Collider2D col) < //если из триггера что то вышло и у обьекта тег "ground" if (col.tag == "ground") is_ground = false; //то вЫключаем переменную "на земле" >void Update() < if (Input.GetKeyDown(KeyCode.Space) && is_ground) //если нажата кнопка "пробел" и игрок на земле player.AddForce(Vector2.up * force, ForceMode2D.Impulse); //то придаем ему силу вверх импульсным пинком >>
Теперь, если запустить игру в редакторе, то можно попрыгать с помощью нажатий пробела! Великолепно! В Unity прыжок сделать совсем не сложно как оказалось))
На этом, урок можно завершить. Пишите, о чем еще хотели-бы прочитать на нашем сайте? И еще раз. Всем добра!)