Unity UI-based Hotspot icons

From AC's Settings Manager, icons can be set up to be drawn over Hotspots using Unity's OnGUI system. This script allows them to instead be rendered using Unity UI, allowing for more control over their apperance.

To use it:

1. Create a new Unity UI Canvas, and set the Canvas component's Render Mode to Screen Space - Overlay
2. Attach an Image as a child, and scale to suit - this will be duplicated for each Hotspot icon at runtime
3. Copy/paste the code below into a new C# file named HotspotIconsUI
4. Attach the new Hotspot Icons UI component to the Canvas's root

HotspotIconsUI.cs:

```
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using AC;

public class HotspotIconsUI : MonoBehaviour
{

 public Image iconToDuplicate;
 public CanvasScaler canvasScaler;
 private Dictionary<Hotspot, Image> hotspotIconDict = new Dictionary<Hotspot, Image> ();

 private void OnValidate ()
 {
 if (canvasScaler == null) canvasScaler = GetComponent<CanvasScaler> ();
 if (iconToDuplicate == null) iconToDuplicate = GetComponentInChildren<Image> ();
 }

 private void Awake ()
 {
 Hotspot[] hotspots = Object.FindObjectsOfType<Hotspot> ();
 foreach (Hotspot hotspot in hotspots)
 {
 if (hotspot.highlight == null) continue;

 Image icon = Instantiate (iconToDuplicate.gameObject).GetComponent<Image> ();
 icon.transform.SetParent (iconToDuplicate.transform.parent);
 icon.gameObject.name += "\_" + hotspot.name;
 hotspotIconDict.Add (hotspot, icon);
 }

 iconToDuplicate.gameObject.SetActive (false);
 }

 private void LateUpdate ()
 {
 foreach (Hotspot hotspot in hotspotIconDict.Keys)
 {
 Image icon = hotspotIconDict[hotspot];
 icon.color = new Color (icon.color.r, icon.color.g, icon.color.b, hotspot.highlight.GetHighlightAlpha ());
 icon.sprite = hotspot.GetMainIcon ().GetAnimatedSprite (true);

 Vector2 screenPos = hotspot.GetIconScreenPosition ();

 float scalerOffset = 1f;

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

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

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

 Rect safeScreenRect = ACScreen.safeArea;
 Vector2 diff = new Vector2 (ACScreen.width, ACScreen.height) - safeScreenRect.position - safeScreenRect.position - safeScreenRect.size;
 screenPos += diff / 2f;

 Vector3 localTargetPositionUI = new Vector3 ((screenPos.x - (ACScreen.width / 2f)) / scalerOffset, (screenPos.y - (ACScreen.height / 2f)) / scalerOffset, icon.rectTransform.transform.localPosition.z);

 icon.rectTransform.localPosition = localTargetPositionUI;
 }
 }

}

```