Никнеймы / подписи объектов [UI]

Достаточно простой, но удобный способ, выводить на экран никнеймы игроков, имена персонажей в ролевой игре, или же, подписи объектов. По сути это обновление и переработка ранее опубликованного проекта, в данной версии, всё переделано под новую систему UI, что открывает больше возможностей для кастомизации, так как нам нужно только один раз настроить шаблон под нужный стиль, а всё остальное делается в автоматическом режиме. Основные возможности. Отключение текста, когда объект вне зоны экрана. Ограничение по количеству символов. Проверка на недопустимые символы и запрещённые слова.

С начало надо добавить шаблон на сцену, это может быть обычный Text UI, на нем главное не забыть выставить нужный пресет:

Никнеймы / подписи объектов [UI]

Кстати говоря, родительский Canvas, должен быть в стандартном режиме Overlay.

Теперь на шаблон вешаем:

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class UITitle : MonoBehaviour {

	public Text title;
	public Transform target;
	public float distance;

	private RectTransform _rect;

	void Start()
	{
		_rect = GetComponent<RectTransform>();
		_rect.sizeDelta = new Vector2(title.preferredWidth, _rect.sizeDelta.y); // авто подстройка по ширине текста
	}

	void LateUpdate()
	{
		Vector3 pos = Camera.main.WorldToScreenPoint(target.position);
		_rect.anchoredPosition = pos;

		if(Vector3.Distance(Camera.main.ScreenToWorldPoint(_rect.position), target.position) > distance)
		{
			title.enabled = false;
		}
		else
		{
			title.enabled = true;
		}
	}
}

В переменной title нужно указать текстовый компонент, остальное оставляем как есть.

Далее, на Canvas цепляем:

using UnityEngine;
using System.Collections;
using System.Text.RegularExpressions;

public class UITitleManager : MonoBehaviour {

	public string[] words = {"один", "два", "три"}; // слова, которые нельзя использовать
	public string pattern = "[@,#,%,&,^,*,/,?,<,>,',+,=,_]"; // символы, которые нельзя использовать
	public int maxTextLength = 15; // максимальная длина текста, в символах
	public float distance = 30; // дистанция от камеры и до объекта, если выше этого значения - выключаем отображение текста
	public UITitle sample; // шаблон для конструктора

	private static UITitleManager _internal;

	void Awake()
	{
		_internal = this;
	}

	public static UITitleManager Internal
	{
		get{return _internal;}
	}

	public string CheckTitle(string text)
	{
		Regex regex = new Regex(pattern);
		Match match = regex.Match(text);

		if(match.Success)
		{
			return "Недопустимые символы!";
		}
			
		foreach(string str in words)
		{
			regex = new Regex(str, RegexOptions.IgnoreCase);

			if(regex.IsMatch(text))
			{
				return "Указанное слово, запрещено использовать!";
			}
		}

		return string.Empty;
	}

	public GameObject AddTitle(Transform target, string text, Color textColor)
	{
		UITitle ui = Instantiate(sample) as UITitle;
		ui.GetComponent<RectTransform>().SetParent(transform);
		ui.target = target;
		ui.title.text = text;
		ui.title.color = textColor;
		ui.distance = distance;
		ui.gameObject.SetActive(false);
		return ui.gameObject;
	}
}

Собственно тут и создается текст, плюс, здесь мы указываем необходимые настройки.

Теперь, подготовка самого объекта. Тут важный момент. Используются функции, когда меш в поле видимости или нет, соответственно скрипт нужно цеплять на основной меш объекта: Mesh Renderer, Sprite Renderer или Skinned Mesh Renderer. Если на объекте не будет одного из компонентов, то скрипт будет работать неправильно.

Итак, компонент:

using UnityEngine;
using System.Collections;

public class UITitleComponent : MonoBehaviour {
	
	public string title = "Object Name";
	public Color titleColor = Color.blue;
	public Transform targetPoint;
	private GameObject _obj;

	void Start()
	{
		string txt = UITitleManager.Internal.CheckTitle(title);

		if(title.Length > UITitleManager.Internal.maxTextLength)
		{
			Debug.Log(this + "Превышен лимит символов.");
		}
		else if(txt.Length > 0)
		{
			Debug.Log(this + txt);
		}
		else
		{
			_obj = UITitleManager.Internal.AddTitle(targetPoint, title, titleColor);
		}
	}

	void OnBecameVisible()
	{
		if(_obj) _obj.SetActive(true);
	}

	void OnBecameInvisible()
	{
		if(_obj) _obj.SetActive(false);
	}

	void OnDestroy()
	{
		Destroy(_obj);
	}

	void OnDisable()
	{
		if(_obj) _obj.SetActive(false);
	}

	void OnEnable()
	{
		if(_obj) _obj.SetActive(true);
	}
}

Указываем имя и цвет, на старте, всё будет добавлено куда нужно.

А targetPoint это точка, где должна "висеть" надпись, например:


То есть, пустышка, дочерний объект. Поднимаем чуть выше над головой персонажа и всё.

Скачать демо:

Внимание! Посетители, находящиеся в группе Гости, не могут скачивать файлы.

Комментариев 1

Офлайн
elinelite 13 сентября 2018
можно ли сделать то же самое, в 2d варианте?
Информация
Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.
  • Дешевый хостинг
  • Яндекс.Метрика