Курсор на базе UI

Еще один вариант замены стандартного курсора, работающий на UI системе. Упрощена настройка смещения спрайта, теперь не нужно задавать вручную в пикселях. Например, для стандартного курсора в виде стрелки, изображение должно быть смещено так, чтобы позиция мыши были в левом верхнем углу картинки. Теперь настройки берутся из pivot’а спрайта, с самой UI картинкой ничего делать не нужно. Смена иконки курсора в данной версии делается через массив спрайтов, при этом каждый спрайт привязан к определенной маске слоя, выбран именно такой способ, потому что в настройках маски можно указать сразу несколько слоев.

Для работы курсора нам понадобиться стандартный UI Image объект.

Теперь, о настройках спрайта. Когда мы импортируем спрайт:

Курсор на базе UI

Можно выбрать один из пресетов Pivot или же настроить вручную, через редактор спрайтов. По умолчанию, у всех спрайтов pivot выставлен по центру.

Теперь сам скрипт:

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

public class GameCursor : MonoBehaviour {

	[SerializeField] private Image cursor;
	private enum Mode {Project3D, Project2D};
	[SerializeField] private Mode mode;
	[SerializeField] private Cursors[] option;
	[SerializeField] private Sprite defaultCursor;
	private static bool visible = true;
	private RectTransform rect;

	[System.Serializable] struct Cursors
	{
		public Sprite sprite;
		public LayerMask layerMask;
	}

	public static void Visible(bool value)
	{
		visible = value;
	}

	void Awake()
	{
		rect = cursor.GetComponent<RectTransform>();
		cursor.raycastTarget = false;
		Cursor.visible = false;
	}

	void LateUpdate()
	{
		if(visible)
		{
			Raycast();

			rect.pivot = new Vector2(cursor.sprite.pivot.x / cursor.sprite.texture.width, cursor.sprite.pivot.y / cursor.sprite.texture.height);
			rect.position = Input.mousePosition;
		}

		if(!visible && cursor.gameObject.activeSelf) cursor.gameObject.SetActive(false);
		else if(visible && !cursor.gameObject.activeSelf) cursor.gameObject.SetActive(true);
	}

	Sprite SetCursor(int layer)
	{
		for(int i = 0; i < option.Length; i++)
		{
			if(((1 << layer) & option[i].layerMask) != 0)
			{
				return option[i].sprite;
			}
		}

		return defaultCursor;
	}

	void Raycast()
	{
		if(mode == Mode.Project3D)
		{
			RaycastHit hit;
			Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

			if(Physics.Raycast(ray, out hit))
			{
				cursor.sprite = SetCursor(hit.collider.gameObject.layer);
			}
			else
			{
				cursor.sprite = SetCursor(-1);
			}
		}
		else
		{
			RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);

			if(hit.transform != null)
			{
				cursor.sprite = SetCursor(hit.collider.gameObject.layer);
			}
			else
			{
				cursor.sprite = SetCursor(-1);
			}
		}
	}
}

Работает как с 2D, как и 3D физикой. Дополнительные иконки курсора настраиваем в массиве Option, нужно лишь указать слои и выбрать соответствующий им спрайт. Всё очень просто.

Если нужно скрыть (false) или показать (true) курсор, используем метод:

GameCursor.Visible(true);


Скачать скрипт и демо:

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

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

Офлайн
превосходно
Информация
Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.
  • Яндекс.Метрика