This script causes Hotspots to be detected based on their position on-screen, as opposed to being based on the cursor or Player character's position. This is similar to the system used by Beyond A Steel Sky, where the Hotspot closest to the centre of an invisible circle on the screen is the one selected.
To use it:
- In the Settings Manager, set your "Hotspot detection method" to "Custom Script".
- Copy the script below into a new C# file named ScreenHotspotDetection.cs
- Create a new GameObject in the scene, and attach the new Screen Hotspot Detection component.
- Set its Inspector's "Normal Max Depth" field, which is how far a way a Hotspot can normally be detected from, as desired
- Optionally, assign icon textures in the Inspector, which will display when nearby Hotspots are detected
- To override the "Normal Max Depth", and have a Hotspot be detect-able from far away, define an Interactive Boundary for that Hotspot.
ScreenHotspotDetection.cs:
using System.Collections.Generic;
using UnityEngine;
using AC;
public class ScreenHotspotDetection : MonoBehaviour
{
public float normalMaxDepth = 2f;
public Texture2D nearbyIcon = null;
public Texture2D nearesetIcon = null;
public float iconSize = 0.025f;
private bool cameraIsActive;
private List<Hotspot> nearbyHotspots = new List<Hotspot>();
private Hotspot nearestHotspot;
private Vector2 screenCircleCentre = new Vector2 (0.7f, 0.5f);
private const float screenCircleRadius = 0.3f;
private void Update ()
{
nearbyHotspots.Clear ();
nearestHotspot = null;
if (KickStarter.stateHandler.IsInGameplay ())
{
float nearestHotspotDistance = Mathf.Infinity;
foreach (Hotspot hotspot in KickStarter.stateHandler.Hotspots)
{
Vector3 worldPosition = hotspot.GetIconPosition ();
if (Vector3.Distance (KickStarter.player.transform.position, worldPosition) > normalMaxDepth)
{
if (hotspot.interactiveBoundary == null || !hotspot.interactiveBoundary.PlayerIsPresent)
{
continue;
}
}
Vector3 viewportPosition = KickStarter.CameraMain.WorldToViewportPoint (worldPosition);
if (viewportPosition.z < 0f) continue;
float thisHotspotDistance = Vector2.Distance (viewportPosition, screenCircleCentre);
if (thisHotspotDistance > screenCircleRadius)
{
nearbyHotspots.Add (hotspot);
continue;
}
if (thisHotspotDistance < nearestHotspotDistance)
{
if (nearestHotspot)
{
nearbyHotspots.Add (nearestHotspot);
}
nearestHotspot = hotspot;
nearestHotspotDistance = thisHotspotDistance;
}
else
{
nearbyHotspots.Add (hotspot);
}
}
KickStarter.playerInteraction.SetActiveHotspot (nearestHotspot);
}
}
private void OnGUI ()
{
if (nearestIcon != null && nearestHotspot)
{
GUI.DrawTexture (AdvGame.GUIBox (nearestHotspot.GetIconScreenPosition (), iconSize), nearesetIcon, ScaleMode.ScaleToFit, true, 0f);
}
if (nearbyIcon != null)
{
foreach (Hotspot hotspot in nearbyHotspots)
{
GUI.DrawTexture (AdvGame.GUIBox (hotspot.GetIconScreenPosition(), iconSize), nearbyIcon, ScaleMode.ScaleToFit, true, 0f);
}
}
}
}