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:

Highlight on certain distance

Highlight on certain distance

Highlight before interacting with persons

Highlight before interacting with persons

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:

Show menu on smaller distance

Show menu on smaller distance

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:

Highlight for inner gameobject

Highlight for inner gameobject

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:

Add highlighter occlusion

Add highlighter occlusion

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.

(Visited 247 times, 1 visits today)