Jump to content
Sign in to follow this  
Константин Орлов

Unity: Как сделать всплывающую подсказку, как в Windows

Recommended Posts

При наведении курсора на объект (как из 3D мира, так и в UI-интерфейсе) появляется всплывающая подсказка, похожая на обычную из интерфейса Windows. 

 

Пример работы всплывающей подсказки на игровом движке Unity

 

Есть 3 скрипта. Один необходимо повесить на Canvas, и два других на объекты, с которых хотите получать всплывающие подсказки. Если это обычный 3D объект, то вешаем на него TooltipText, если это UI-объект, то TooltipTextUI. После чего в инспекторе конкретного объекта в компоненте скрипта указываем текст подсказки.

Как установить всплывающие подсказки в Unity3d

  1. Создаем Canvas; удаляем компонент Graphic Raycaster, так как нам не нужно взаимодействие курсора с Tooltip-ом (нет картинки этого действия); вешаем на него скрипт Tooltip:
    Create Canvas.jpgCanvas Tooltip.jpg
  2. Внутри него создаем 3 объекта: 1) Картинка фона (GameObject > UI > Image); 2) Картинка стрелочки-уголочка; 3) Элемент UI-текст.
  3. Скачиваем картинки в пакете со сценой примером (23кб всего), импортируем в проект, берем из папки Sprite картинки: на фон выставляем картинку Box, на стрелочку Arrow.
  4. Делаем дочерними от фоновой картинки (Box) картинку со стрелочкой и UI-текст.
    Hierarchy.jpg
  5. Выравниваем элементы в инспекторе: для стрелочки и фона bottom/left, для текста stretch/stretch;
    BoxArrowRect.jpgTextRect.jpg
  6. В инспекторе Canvas за счет прикрепления скрипта появились настройки, переносим в соответствующие поля созданные нами GameObject'ы: в поле Box - картинку фона, в Arrow - стрелочку, в Box Text - UI-элемент текста;
    Perenos.jpg

 

Теперь можно на любой объект на сцене, который имеет коллайдер, повесить скрипт TooltipText, и в инспекторе объекта задать текст подсказки. Если это объект UI, то вешаем скрипт TooltipTextUI.

  • Настройки шрифта задаются в инспекторе Canvas, на котором весит скрипт Tooltip.
  • Вы можете использовать свои картинки для фона, но для начала советую попробовать с этими, чтобы быть уверенными, что ничего не съезжает из-за других картинок.
  • Насколько скрипт грамотно написан и оптимизирован не знаю, я пока недостаточно разбираюсь, но я его поставил - работает.
  • Задавать все объекты обязательно (фон, стрелочку), иначе работать не будет. Я пробовал без стрелочки, ибо не нужна она мне особо, но тогда видимо нарушается логика скрипта.
  • Если подсказка очень короткая, например, 4 буквы "Стол" или "Стена", то стрелочка отображаться будет немного криво, поэтому мне пришлось увеличить текст, например, до "Это стол" или "Это стена".

Источник: взято отсюда.

Вы можете скачать скрипты и картинки (+демо сцена) отсюда UnityTooltip.unitypackage, либо с источника. Также скрипты выложены ниже:

 

Скрипт Tooltip для Canvas 

Спойлер

// NULLcode Studio © 2015
// null-code.ru

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

public class Tooltip : MonoBehaviour {

	public static string text;
	public static bool isUI;

	public Color BGColor = Color.white;
	public Color textColor = Color.black;
	public enum ProjectMode {Tooltip3D = 0, Tooltip2D = 1};
	public ProjectMode tooltipMode = ProjectMode.Tooltip3D;
	public int fontSize = 14; // размер шрифта
	public int maxWidth = 250; // максимальная ширина Tooltip
	public int border = 10; // ширина обводки
	public RectTransform box;
	public RectTransform arrow;
	public Text boxText;
	public Camera _camera;
	public float speed = 10; // скорость плавного затухания и проявления

	private Image[] img;
	private Color BGColorFade;
	private Color textColorFade;

	void Awake()
	{
		img = new Image[2];
		img[0] = box.GetComponent<Image>();
		img[1] = arrow.GetComponent<Image>();
		box.sizeDelta = new Vector2(maxWidth, box.sizeDelta.y);
		BGColorFade = BGColor;
		BGColorFade.a = 0;
		textColorFade = textColor;
		textColorFade.a = 0;
		isUI = false;
		foreach(Image bg in img)
		{
			bg.color = BGColorFade;
		}
		boxText.color = textColorFade;
		boxText.alignment = TextAnchor.MiddleCenter;
	}

	void LateUpdate()
	{
		bool show = false;
		boxText.fontSize = fontSize;

		if(tooltipMode == ProjectMode.Tooltip3D)
		{
			RaycastHit hit;
			Ray ray = _camera.ScreenPointToRay(Input.mousePosition);
			if(Physics.Raycast(ray, out hit))
			{
				if(hit.transform.GetComponent<TooltipText>())
				{
					text = hit.transform.GetComponent<TooltipText>().text;
					show = true;
				}
			}
		}
		else
		{
			RaycastHit2D hit = Physics2D.Raycast(_camera.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);
			if(hit.transform != null)
			{
				if(hit.transform.GetComponent<TooltipText>())
				{
					text = hit.transform.GetComponent<TooltipText>().text;
					show = true;
				}
			}
		}

		boxText.text = text;
		float width = maxWidth;
		if(boxText.preferredWidth <= maxWidth - border) width = boxText.preferredWidth + border;
		box.sizeDelta = new Vector2(width, boxText.preferredHeight + border);

		float arrowShift = width / 4; // сдвиг позиции стрелки по Х

		if(show || isUI)
		{
			float arrowPositionY = -(arrow.sizeDelta.y / 2 - 1); // позиция стрелки по умолчанию (внизу)
			float arrowPositionX = arrowShift;
			
			float curY = Input.mousePosition.y + box.sizeDelta.y / 2 + arrow.sizeDelta.y;
			Vector3 arrowScale = new Vector3(1, 1, 1);
			if(curY + box.sizeDelta.y / 2 > Screen.height) // если Tooltip выходит за рамки экрана, в данном случаи по высоте
			{
				curY = Input.mousePosition.y - box.sizeDelta.y / 2 - arrow.sizeDelta.y;
				arrowPositionY = box.sizeDelta.y + (arrow.sizeDelta.y / 2 - 1);
				arrowScale = new Vector3(1, -1, 1); // отражение по вертикале
			}
			
			float curX = Input.mousePosition.x + arrowShift;
			if(curX + box.sizeDelta.x / 2 > Screen.width)
			{
				curX = Input.mousePosition.x - arrowShift;
				arrowPositionX = width - arrowShift;
			}
			
			box.anchoredPosition = new Vector2(curX, curY);
			
			arrow.anchoredPosition = new Vector2(arrowPositionX, arrowPositionY);
			arrow.localScale = arrowScale;

			foreach(Image bg in img)
			{
				bg.color = Color.Lerp(bg.color, BGColor, speed * Time.deltaTime);
			}
			boxText.color = Color.Lerp(boxText.color, textColor, speed * Time.deltaTime);
		}
		else
		{
			foreach(Image bg in img)
			{
				bg.color = Color.Lerp(bg.color, BGColorFade, speed * Time.deltaTime);
			}
			boxText.color = Color.Lerp(boxText.color, textColorFade, speed * Time.deltaTime);
		}
	}
}

 

 

Скрипт TooltipText для любого объекта на сцене (имеющего коллайдер)

Спойлер

// NULLcode Studio © 2015
// null-code.ru

using UnityEngine;
using System.Collections;

public class TooltipText : MonoBehaviour {

	public string text;

}

 

 

Скрипт TooltipTextUI для объектов UI (им колайдер не требуется)

Спойлер

// NULLcode Studio © 2015
// null-code.ru

using UnityEngine;
using UnityEngine.EventSystems;
using System.Collections;

public class TooltipTextUI : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler {
	
	public string text;
	
	void IPointerEnterHandler.OnPointerEnter(PointerEventData e)
	{
		Tooltip.text = text;
		Tooltip.isUI = true;
	}
	
	void IPointerExitHandler.OnPointerExit(PointerEventData e)
	{
		Tooltip.isUI = false;
	}
}

 

 

Картинки тоже можно скачать прямо с поста (но не факт, что заработают эти, возможно нужно именно из файлов брать):

Arrow:

arrow.png

Box:

box.png

Share this post


Link to post
Share on other sites
 

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

  • Если у вас есть факты, вещдоки, и свидетельские показания, то обратитесь: vk.com/orkons или orkons@ya.ru, они будут проверены и опубликованы. Возможна беседа под запись с публикацией на YouTube.
    Все материалы на сайте сделаны в пародийных целях и являются художественным вымыслом, все совпадения с реальными людьми и событиями случайны.

Powered by Invision Community
Поддержка Invision Community в России