Highlighting Unity GameObjects with Highlighter Asset
For our Unity game Erwin’s timewarp we have a cool feature to highlight objects the player can interact with. We use a highlighting system, a great asset you can get from the assetstore to implement this feature now.
Perhaps you know this kind of highlighting from games like Slender Man which is made with Unity: when the player has a certain distance to an object he can interact with the gameobject gets highlighted like this:
With the highlighter asset we use this can be implemented very easily.
We wrote the following script to add a highlighter dynamically:
using HighlightingSystem; using System; using System.Collections.Generic; using System.Linq; using System.Text; using UnityEngine; namespace Assets.ErwinsTimewarp.Scripts { public class IInteractable : MonoBehaviour { protected float _showInteractionOptionDistance = 6.0f; protected float _interactionDistance = 3.0f; protected Vector3 _rayCastOffset = Vector3.zero; private Highlighter _highlighter; void Awake() { _highlighter = gameObject.AddComponent<Highlighter>(); _highlighter.ConstantParams(Color.red); _rayCastOffset = new Vector3(0.0f, 5.0f, 0.0f); } void FixedUpdate() { if (_highlighter != null) { float distance = Vector3.Distance(PlayerController.Instance.PlayerTransform.position, this.transform.position); bool active = (distance <= _showInteractionOptionDistance); if (active) _highlighter.ConstantOn(); else _highlighter.ConstantOff(); // Okay, we have the appropriate distance to show that we can do something with this object if (active) { // Now we want to know if we can show the action menu if (distance <= _interactionDistance) { RaycastHit hit; Vector3 thisPos = this.transform.position; thisPos += _rayCastOffset; // If a raycast from the check position to the player hits something... if (Physics.Raycast(thisPos, PlayerController.Instance.PlayerTransform.position - thisPos, out hit)) { // ... if it is not the player... if (hit.transform != PlayerController.Instance.gameObject.transform) { active = false; } } } else { active = false; } } if(active) { // TODO: show menu... } } } internal void RemoveInteractOption() { Destroy(_highlighter); } #endregion } }
In this script we distinguish between the distance the player needs to have so that the highlighter is shown (showInteractionOptionDistance) and a distance which is smaller than that (interactiondistance) for which an interaction menu will be shown:
After you interacted with an object (like the fridge in the example above) you can remove the interaction option (method RemoveInteractOption) if you do not need it anymore:
To avoid that the highlight is drawn over other objects (like the player) you can add a highlighter occlusion component and set SeeThroughto true. Now the player will always appear in front of the painted highlighting:
The system is very flexible and had a nice and clean API, it tooks us about an hour to use it for all scripts because we added this logic to a C# base-class.