And I’m back…almost! It has been a very busy 4 months, Uni and Work both vying for my attention harder than ever especially with the Covid cloud of doom hovering overhead. However, two more weeks of uni to learn combinatorics and I’m done for the year since there are no exams! Woohoo!

Now I have a little bit of breathing room, I thought I would have a little play in my own time with Unity and make some little bits and pieces I know I will need later. Here is a tiny little something…

Sprite Markers

So, quite often in 3D apps, you see these little 2.5D markers that hover over objects that have some sort of Symbol (like an information or warning icon). Unity has these and they are called Gizmos and they are really easy to implement. However, these are UnityEditor only Gizmos and won’t appear in-game… so, mini-challenge post coursework workout just to clear my mind was to create my own version.

So, what does this mini-challenge entail? Well, they need to rotate to face the Camera always, but to only rotate about the Y-Axis (Z-Axis if you are more familiar with 3D apps like Revit). I also wanted them to stand out and be aesthetically pleasing, so have them change colour over time and bounce/bob so they are super obvious to the user. Also, to be easy-to-use for the non-developer where you can just apply the script and it is pretty much ready to go. So, with all these little considerations, here is what I made…

The Code…

using UnityEngine;

// Require a Sprite Renderer...
[RequireComponent(typeof(SpriteRenderer))]
public class SpriteMarker : MonoBehaviour
{
    #region Inspector Properties

    [Tooltip("Use the Materials Albeido Colour as start colour.")]
    public bool UseDefaultStartColour = true;

    [Tooltip("The desired marker Start Colour.")]
    [ColorUsage(true)]
    public Color StartColour = Color.white;

    [Tooltip("The desired marker End Colour.")]
    [ColorUsage(true)]
    public Color EndColour = Color.grey;
    [Range(0.1f, 2f)]

    [Tooltip("Duration between colour switching/bounce")]
    public float duration = 1f;

    [Tooltip("Enable bounce to markers")]
    public bool Bounce = true;

    #endregion

    #region Private Properties

    /// <summary>
    /// The Sprite Renderer attached to the gameobject.
    /// </summary>
    private SpriteRenderer _renderer;

    /// <summary>
    /// The y value of the transforms position.
    /// </summary>
    private float _yVal = 0;

    #endregion

    #region Private Methods

    /// <summary>
    /// When Application starts.
    /// </summary>
    private void Start()
    {
        // Get markers position Y Value to use later when bouncing...
        _yVal = transform.position.y;

        // Get markers renderer to use for changing colour...
        _renderer = transform.GetComponent<SpriteRenderer>();
        
        // If UseDefaultStartColour then get the colour of the material applied to the marker. Otherwise, set materials colour to the user selected Start Colour...
        if (UseDefaultStartColour)            
            StartColour = _renderer.color;
        else
        {
            //_renderer.material.color = StartColour;
            _renderer.color = StartColour;
        }
    }

    /// <summary>
    /// Update called once per frame.
    /// </summary>
    void Update()
    {
        // Get the Main Camera's position...
        var camPos = Camera.main.transform.position;
        // Create target position which is the camera's postion at the same height as markers position...
        var tarPos = new Vector3(camPos.x, transform.position.y, camPos.z);

        // Update marker to look at the target...
        transform.LookAt(tarPos);
        // Flip forward direction...
        transform.forward = transform.forward * -1;        

        // Lerp value between duration...
        float t = Mathf.PingPong(Time.time, duration) / duration;
        // Lerp colours based on lerp value (t)...        
        _renderer.color = Color.Lerp(StartColour, EndColour, t);

        // If Bounce Enabled, then update markers y-value based on lerp value (t)...
        if (Bounce)
            transform.position = new Vector3(transform.position.x, _yVal + t/5, transform.position.z);
    }

    #endregion
}

You could add further to this by making them selectable, which is relatively easy using Physics.Raycast and perhaps a LayerMask to dynamically show UI or trigger an animation.

Anyway, hope you find this little thing useful. Thanks for reading as always! 🙂

Advertisement