Смена иконки курсора при наведении

В настройках проекта Unity можно назначить курсор по умолчанию, но тогда просто системный курсор будет заменен, да и к тому-же качество получившейся иконки не ахти выходит, и размер таким образом не отрегулировать. Кроме всего прочего, как быть с например, стратегиями? Или любой другой игре, где необходимо менять иконку курсора в зависимости от текущей цели, либо просто подсказывать игроку о том, что данный объект интерактивный. Поэтому будем рисовать нужные нам иконки через скрипт, плюс добавим опцию для выбора, 2D физика или 3D физика, используется в проекте.

Итак, нарисуем несколько курсоров для нашего проекта. Все изображения должны быть одинаковые по ширине и высоте, исходные можно рисовать, например, 150х150. В качестве изображения по умолчанию, указатель лучше повернуть так, чтобы он "смотрел" в верхний левый угол, ну и добавить немного размытия. Сохраняем картинки в формате PNG.


В Unity импортировать, как текстуру с параметрами:

Смена иконки курсора при наведении



Теперь, осталось добавить пустой объект на сцену и повесить на него скрипт GameCursor:

using UnityEngine;
using System.Collections;

public class GameCursor : MonoBehaviour {

	public Texture2D cursorNormal;
	public Texture2D cursorEnemy;
	public Texture2D cursorInfo;
	public int size = 30; // размер курсора по ширине и высоте
	public enum ProjectMode {Project3D = 0, Project2D = 1};
	public ProjectMode mode = ProjectMode.Project3D;
	private Vector2 offset;
	private Texture2D cursor;

	void Awake () 
	{
		Cursor.visible = false; // скрываем системный курсор
		if(mode == ProjectMode.Project2D) Camera.main.orthographic = true; // для RaycastHit2D, камера должна быть в ортогональном режиме
	}

	void MainCursor(string tags)
	{
		if(tags == "Enemy" || tags == "Target")
		{
			offset = new Vector2(-size/2, -size/2); // смещение к центру
			cursor = cursorEnemy;
		}
		else if(tags == "Info")
		{
			offset = new Vector2(-size/2, -size/1.2f);
			cursor = cursorInfo;
		}
		else // курсор по умолчанию
		{
			offset = Vector2.zero;
			cursor = cursorNormal;
		}
	}

	void Update () 
	{
		if(mode == ProjectMode.Project3D)
		{
			RaycastHit hit;
			Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
			if (Physics.Raycast(ray, out hit))
			{
				MainCursor(hit.transform.tag);
			}
			else // если луч никуда не попадет
			{
				offset = Vector2.zero;
				cursor = cursorNormal;
			}
		}
		else
		{
			RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);
			if(hit.transform != null)
			{
				MainCursor(hit.transform.tag);
			}
			else
			{
				offset = Vector2.zero;
				cursor = cursorNormal;
			}
		}
	}

	void OnGUI () 
	{
		Vector2 mousePos = Event.current.mousePosition;
		GUI.depth = 999; // поверх остальных элементов
		GUI.Label(new Rect(mousePos.x + offset.x, mousePos.y + offset.y, size, size), cursor);
	}
}

Ищем цели по тегам, тут указаны просто для примера. Не забудьте их изменить, перед тестированием. Вот, как-то так...

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

Офлайн
DayFall 20 октября 2015
Использовать OnGUI() я бы не стал, так как это устаревшая система, так что незачёт.
http://docs.unity3d.com/ru/current/Manual/GUIScriptingGuide.html
Офлайн
DayFall,
я бы стал использовать OnGui, хоть это и устаревшая система, мне она по крайней мере понятна и проста в использовании
Информация
Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.
  • Яндекс.Метрика