Иногда в игре игроку необходимо указать, в каком направлении находится какая-то цель. Этим мы и займемся. В этой статье я хочу показать вам как при помощи скриптов можно настроить в своем проекте отображение указателей целей.
Для начала подготовим сцену, добавим плоскость, стандартного персонажа и 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);
}
Видео:Как сделать указатель на врагов в Unity?Скачать
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);
Видео:КАК СДЕЛАТЬ UI УКАЗАТЕЛЬ НА 3D ОБЪЕКТ | Unity C#Скачать
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);
}
}
}Это скрипт мы вешаем на Canvas и в строке Indicators Container указываем этот же Canvas

Далее добавим пустышку на сцену и сохраним ее как префаб в папку Prefabs и назовем это префаб Indicator. Создадим еще один скрипт с названием Indicator и содержанием:
using UnityEngine;
using UnityEngine.UI;
namespace ScreenIndicators
{
public class Indicator : MonoBehaviour
{
public Image Image;
Видео:Unity - указатель цели [null-code.ru]Скачать
[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;
}
}
}Этот скрипт мы поместим на префаб Indicator и можно указать галочки отображения и поворота указателей, так же цвет и иконки (иконки для указателей можно взять здесь).

Ну и последний шаг, создаем еще один скрипт Scene:
using System.Collections.Generic;
using ScreenIndicators;
using UnityEngine;
public class DemoScene : MonoBehaviour
{
Видео:Плавный поворот к цели в Unity и вращение до указанного угла / Как создать игру [Урок 128]Скачать
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);
}
}Поместим этот скрипт на персонажа и указываем Canvas, префаб Indicator, Камеру персонажа и 4 куба как цели.

Теперь можно проверить сцену, запускаем игру и видим, что указатели, показывают, в каком направлении находятся наши кубы.

(Информация и скрипты взяты с этого сайта)
🎦 Видео
Unity 5. Изменение указателя, который сосредоточен в центре.Скачать

Как сделать 2D указатель на объект в Unity3D/ 2D pointer in Unity3DСкачать

Unity - плавный поворот к целиСкачать

Цели и выделение объектов | Unity 5Скачать

УДАЛЯЙ UNITY!Скачать

КАК СДЕЛАТЬ МЕНЮ В UNITY / ЛЁГКИЙ И ПОНЯТНЫЙ ВИДЕОУРОК UI ЭЛЕМЕНТЫ И SCENE MANAGEMENTСкачать

ИНТЕРФЕЙС UNITY ЗА 5 МИНУТСкачать

Как добавить фигурную кнопку (Unity быстрогайды)Скачать

[UNITY 5] UI Элементы для создания интерфейса (Canvas,text,image и т.д)Скачать
![[UNITY 5] UI Элементы для создания интерфейса (Canvas,text,image и т.д)](https://i.ytimg.com/vi/rI103EogbQU/0.jpg)
Физика в Unity - 5. ForceModeСкачать

Unity для новичков за 20 минут | Gamicle #unity #gamedev #gamicleСкачать

NavMesh в Unity - Случайные точки, проверка досягаемости и расстояния / Как создать игру [Урок 102]Скачать
![NavMesh в Unity - Случайные точки, проверка досягаемости и расстояния / Как создать игру [Урок 102]](https://i.ytimg.com/vi/REQ9Np9F-uw/0.jpg)
Unity 5: Гайд — Как настроить освещениеСкачать

ВСЕ про Quaternions в Unity - вращение объектовСкачать




![Unity - указатель цели [null-code.ru]](https://i.ytimg.com/vi/j7Z1fnJAaBs/0.jpg)
![Плавный поворот к цели в Unity и вращение до указанного угла / Как создать игру [Урок 128]](https://i.ytimg.com/vi/pr8cTCLeL5w/0.jpg)







