Иногда в игре игроку необходимо указать, в каком направлении находится какая-то цель. Этим мы и займемся. В этой статье я хочу показать вам как при помощи скриптов можно настроить в своем проекте отображение указателей целей.
Для начала подготовим сцену, добавим плоскость, стандартного персонажа и 4 куба.
Персонажем мы будем управлять, а кубы будут служить в качестве целей.
Далее добавим компонент Canvas и создадим новый скрипт с названием IndicatorsManager и с таким содержимым:
using System.Collections.Generic; using System.Linq; using UnityEngine; namespace ScreenIndicators { public class IndicatorsManager : MonoBehaviour { public Canvas IndicatorsContainer; public int IndicatorSize = 100; private List _indicators = new List(); private float _border; private float _halfScreenHeight; private float _halfScreenWidth; public void AddIndicator(Transform target, Indicator indicatorPrefab) { if (GetIndicatorByTarget(target) != null) return; var newIndicator = InstantiateIndicator(indicatorPrefab); newIndicator.Target = target; _indicators.Add(newIndicator); } public void RemoveIndicator(Transform target) { var indicator = GetIndicatorByTarget(target); if (indicator == null) return; _indicators.Remove(indicator); Destroy(indicator.gameObject); }public bool IsTargetExist(Transform target) { var indicator = GetIndicatorByTarget(target); return indicator != null; } private void Start() { _halfScreenHeight = Screen.height / 2f; _halfScreenWidth = Screen.width / 2f; if (IndicatorsContainer == null) { Debug.LogError("Need canvas for Indicators"); return; } _border = IndicatorSize / 2f; } private void LateUpdate() { var indicatorsToRemove = new List(); foreach (var indicator in _indicators) { if (indicator.Target == null) { indicatorsToRemove.Add(indicator); continue; } UpdateIndicator(indicator); } if (indicatorsToRemove.Count <= 0) return; foreach (var indicator in indicatorsToRemove) { _indicators.Remove(indicator); Destroy(indicator.gameObject); } } private Indicator InstantiateIndicator(Indicator indicatorPrefab) { var indicator = Instantiate(indicatorPrefab, IndicatorsContainer.transform, false); var rect = indicator.GetComponent(); indicator.transform.localScale = Vector3.one; rect.sizeDelta = new Vector2(IndicatorSize, IndicatorSize);Видео:Как сделать указатель на врагов в Unity?Скачать
return indicator; } private void UpdateIndicator(Indicator indicator) { var screenPoint = Camera.main.WorldToScreenPoint(indicator.Target.localPosition); Vector3 newPosition; float angle; var heading = indicator.Target.position - Camera.main.transform.position; var isBehindCamera = Vector3.Dot(Camera.main.transform.forward, heading) < 0; if (screenPoint.x > Screen.width - _border || screenPoint.x < _border || screenPoint.y > Screen.height - _border || screenPoint.y < _border || isBehindCamera) { indicator.IsOnScreen = false; angle = Mathf.Atan2(screenPoint.y - _halfScreenHeight, screenPoint.x - _halfScreenWidth); float x, y; if(screenPoint.x - _halfScreenWidth > 0) { // right x = _halfScreenWidth - _border; y = x * Mathf.Tan(angle); } else { // left x = -_halfScreenWidth + _border; y = x * Mathf.Tan(angle); } if(y > _halfScreenHeight - _border) { // up y = _halfScreenHeight - _border; x = y / Mathf.Tan(angle); } if(y < -_halfScreenHeight + _border) { // down y = -_halfScreenHeight + _border; x = y / Mathf.Tan(angle); } if(isBehindCamera) { x = -x; y = -y; } newPosition = new Vector3(x, y, 0); } else { indicator.IsOnScreen = true; var x = screenPoint.x - _halfScreenWidth; var y = screenPoint.y - _halfScreenHeight; newPosition = new Vector3(x, y, 0); } indicator.transform.localPosition = newPosition; //rotate if ((indicator.IsOnScreen && indicator.RotateOnScreen) || (!indicator.IsOnScreen && indicator.RotateOffScreen)) { angle = isBehindCamera ? Mathf.Atan2(-(screenPoint.y - _halfScreenHeight), -(screenPoint.x - _halfScreenWidth)) : Mathf.Atan2(screenPoint.y - _halfScreenHeight, screenPoint.x - _halfScreenWidth); } else { angle = 90 * Mathf.Deg2Rad; } indicator.transform.localEulerAngles = new Vector3(0, 0, angle * Mathf.Rad2Deg - 90); } private Indicator GetIndicatorByTarget(Transform target) { return _indicators.FirstOrDefault(indicator => indicator.Target == target); } } }Видео:Unity - указатель цели [null-code.ru]Скачать
Это скрипт мы вешаем на Canvas и в строке Indicators Container указываем этот же Canvas
Далее добавим пустышку на сцену и сохраним ее как префаб в папку Prefabs и назовем это префаб Indicator. Создадим еще один скрипт с названием Indicator и содержанием:
using UnityEngine; using UnityEngine.UI; namespace ScreenIndicators { public class Indicator : MonoBehaviour { public Image Image;[HideInInspector] public Transform Target; [HideInInspector] public bool IsOnScreen; public bool ShowOnScreen; public bool RotateOnScreen; public Sprite OnScreenSprite; public Color OnScreenSpriteColor; public bool ShowOffScreen; public bool RotateOffScreen; public Sprite OffScreenSprite; public Color OffScreenSpriteColor; private void Update() { if (IsOnScreen) { Image.sprite = OnScreenSprite; Image.color = OnScreenSpriteColor; Image.enabled = ShowOnScreen; return; } Image.sprite = OffScreenSprite; Image.color = OffScreenSpriteColor; Image.enabled = ShowOffScreen; } } }Видео:КАК СДЕЛАТЬ UI УКАЗАТЕЛЬ НА 3D ОБЪЕКТ | Unity C#Скачать
Этот скрипт мы поместим на префаб Indicator и можно указать галочки отображения и поворота указателей, так же цвет и иконки (иконки для указателей можно взять здесь).
Ну и последний шаг, создаем еще один скрипт Scene:
using System.Collections.Generic; using ScreenIndicators; using UnityEngine; public class DemoScene : MonoBehaviour {public IndicatorsManager IndicatorsManager; public Indicator IndicatorPrefab; public Transform Camera; public List Targets; private void Start() { AddIndicatorsToAllTargets(); } private void Update() { Camera.Rotate(Camera.up, 10f * Time.deltaTime); } // UI buttons click public void AddIndicatorsToAllTargets() { foreach (var target in Targets) { IndicatorsManager.AddIndicator(target, IndicatorPrefab); } } public void RemoveIndicatorsFromAllTargets() { foreach (var target in Targets) { IndicatorsManager.RemoveIndicator(target); } } public void DestroyRandomTarget() { if (Targets.Count <= 0) return; var randomTarget = Targets[Random.Range(0, Targets.Count)]; Targets.Remove(randomTarget); Destroy(randomTarget.gameObject); } }Видео:Unity - плавный поворот к целиСкачать
Поместим этот скрипт на персонажа и указываем Canvas, префаб Indicator, Камеру персонажа и 4 куба как цели.
Теперь можно проверить сцену, запускаем игру и видим, что указатели, показывают, в каком направлении находятся наши кубы.
(Информация и скрипты взяты с этого сайта)
💡 Видео
Как сделать 2D указатель на объект в Unity3D/ 2D pointer in Unity3DСкачать
Плавный поворот к цели в Unity и вращение до указанного угла / Как создать игру [Урок 128]Скачать
Цели и выделение объектов | Unity 5Скачать
Unity 5. Изменение указателя, который сосредоточен в центре.Скачать
Как добавить фигурную кнопку (Unity быстрогайды)Скачать
ИНТЕРФЕЙС UNITY ЗА 5 МИНУТСкачать
КАК СДЕЛАТЬ МЕНЮ В UNITY / ЛЁГКИЙ И ПОНЯТНЫЙ ВИДЕОУРОК UI ЭЛЕМЕНТЫ И SCENE MANAGEMENTСкачать
УДАЛЯЙ UNITY!Скачать
[UNITY 5] UI Элементы для создания интерфейса (Canvas,text,image и т.д)Скачать
NavMesh в Unity - Случайные точки, проверка досягаемости и расстояния / Как создать игру [Урок 102]Скачать
ВСЕ про Quaternions в Unity - вращение объектовСкачать
Unity 5: Гайд — Как настроить освещениеСкачать
Unity для новичков за 20 минут | Gamicle #unity #gamedev #gamicleСкачать
Физика в Unity - 5. ForceModeСкачать