Unity UI-based cursor

**NOTE: This feature is now included in the official AC release.**

This script allows you to rely on Unity UI to render the cursor, making it possible to add e.g. animation effects. It works by positioning a RectTransform to match the position of the system cursor. It can be used in one of two ways:

1. Modify the texture field of a RawImage component to match the graphic AC wants to set its own cursor to
2. Modify Animator parameters to control playback of animations that control the UI's appearance

To use the script:

1. In the Cursor Manager, set the Cursor rendering field to Hardware
2. Create a new Unity UI Canvas, and either create a RawImage component to act as the cursor, or configure an Animator to change the UI's appearance based on a "ClickID" integer, an "InventoryID" integer, a "CursorIsVisible" boolean, and "Click" trigger.
3. Attach the script below to the Canvas and configure the Inspector to suit your needs.
4. Attach a Canvas Group component to the root and uncheck "Interactable".
5. (Optional) To spawn this automatically, make the UI Canvas a prefab and remove it from the scene. Then, create an ActionList asset to run when the game begins (via the Settings Manager), and use it to create an "Object: Call event" Action that triggers this script component's "Spawn In Scene" function on the prefab.

UnityUICursor.cs:

```
using UnityEngine;
using UnityEngine.UI;
using AC;

public class UnityUICursor : MonoBehaviour
{

 public Texture2D emptyTexture;
 public Animator \_animator;
 public string cursorIDIntParameter = "CursorID";
 public string inventoryIDIntParameter = "InventoryID";
 public string cursorVisibleBoolParameter = "CursorIsVisible";
 public string clickTriggerParameter = "Click";

 public RawImage rawImageToControl;
 public RectTransform rectTransformToPosition;
 public CanvasScaler rootCanvasScaler;

 public void SpawnInScene ()
 {
 GameObject newInstance = Instantiate (gameObject);
 newInstance.name = gameObject.name;
 DontDestroyOnLoad (newInstance);
 }

 private void OnEnable ()
 {
 if (KickStarter.cursorManager.cursorRendering == CursorRendering.Software)
 {
 Debug.LogWarning ("Cursor rendering must be set to 'Hardware' for the UnityUICursor script to take effect.");
 }
 EventManager.OnSetHardwareCursor += OnSetHardwareCursor;
 }

 private void OnDisable ()
 {
 EventManager.OnSetHardwareCursor -= OnSetHardwareCursor;
 }

 private void Update ()
 {
 if (\_animator != null)
 {
 if (!string.IsNullOrEmpty (cursorIDIntParameter)) \_animator.SetInteger (cursorIDIntParameter, KickStarter.playerCursor.GetSelectedCursorID ());
 if (!string.IsNullOrEmpty (inventoryIDIntParameter)) \_animator.SetInteger (inventoryIDIntParameter, (KickStarter.runtimeInventory.SelectedItem != null) ? KickStarter.runtimeInventory.SelectedItem.id : -1);

 if (Input.GetMouseButtonDown (0))
 {
 if (!string.IsNullOrEmpty (clickTriggerParameter)) \_animator.SetTrigger (clickTriggerParameter);
 }
 }

 if (rectTransformToPosition != null)
 {
 Vector2 \_position = KickStarter.playerInput.GetMousePosition ();

 float scalerOffset = 1f;
 if (rootCanvasScaler != null && rootCanvasScaler.enabled && rootCanvasScaler.uiScaleMode == CanvasScaler.ScaleMode.ScaleWithScreenSize)
 {
 switch (rootCanvasScaler.screenMatchMode)
 {
 case CanvasScaler.ScreenMatchMode.MatchWidthOrHeight:
 float match = rootCanvasScaler.matchWidthOrHeight;
 scalerOffset = (Screen.width / rootCanvasScaler.referenceResolution.x) \* (1 - match) + (Screen.height / rootCanvasScaler.referenceResolution.y) \* match;
 break;

 case CanvasScaler.ScreenMatchMode.Expand:
 scalerOffset = Mathf.Min (Screen.width / rootCanvasScaler.referenceResolution.x, Screen.height / rootCanvasScaler.referenceResolution.y);
 break;

 case CanvasScaler.ScreenMatchMode.Shrink:
 scalerOffset = Mathf.Max (Screen.width / rootCanvasScaler.referenceResolution.x, Screen.height / rootCanvasScaler.referenceResolution.y);
 break;
 }
 }

 rectTransformToPosition.localPosition = new Vector3 ((\_position.x - (Screen.width / 2f)) / scalerOffset, (\_position.y - (Screen.height / 2f)) / scalerOffset, rectTransformToPosition.localPosition.z);
 }
 }

 private void OnSetHardwareCursor (Texture2D texture, Vector2 clickOffset)
 {
 if (emptyTexture != null)
 {
 Cursor.SetCursor (emptyTexture, Vector2.zero, CursorMode.Auto);
 }

 if (\_animator != null && !string.IsNullOrEmpty (cursorVisibleBoolParameter))
 {
 \_animator.SetBool (cursorVisibleBoolParameter, (texture != null));

 if (rawImageToControl != null && texture != null)
 {
 rawImageToControl.texture = texture;
 }
 }
 else
 {
 if (rawImageToControl != null)
 {
 rawImageToControl.texture = (texture != null) ? texture : emptyTexture;
 }
 }
 }

}

```