This script allows Hotspot icons to be drawn uwing Unity UI, allowing for smooth motion, or animating them if needed.
To use it:
- Create a new C# script named HotspotIconsUI and copy/paste the code below
- Create a new Unity UI Canvas, and attach an Image as a child. This Image will be used as the basis for the icons.
- Attach the new Hotspot Icons UI component to the Canvas, and fill in its Inspector
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;
}
}
}