[Unity Scripts] Gauge and Meter C# Scripts for your Unity Game

edited in Tutorials

The Random Jittering Gauge Script
This is a Single Needle Version of the next script "Fuel Gauge"

using UnityEngine;

public class Indicator_General : MonoBehaviour
{
    // Sets a "Needle" gameobject to the start rotation and jitters based on wanderspeed and amountToWander ... good for random meters like pressure, current, etc

    private Quaternion m_OriginalRotation;

    public float _AngleToStart = 100.0f;
    public float _AmountToWander = 0.5F;
    private float _rotationAngle;

    [Range(0, 1)]
    public float wanderspeed = 1.0f;

    private void Start()
    {
        m_OriginalRotation = transform.localRotation;
    }

    private void FixedUpdate()
    {
        _rotationAngle = UnityEngine.Random.Range(_AmountToWander, -_AmountToWander) + _AngleToStart;
        Quaternion newQuat = m_OriginalRotation * Quaternion.Euler(0, _rotationAngle, 0);
        transform.localRotation = Quaternion.Lerp(m_OriginalRotation, newQuat, Time.time * wanderspeed);
    }
}


The Fuel Gauge Script
This is a Dual Needle "Fuel Gauge"

using UnityEngine;

public class Instru_Fuel : MonoBehaviour {

    public GameObject needle_LOX;
    [Range(0, 360)]
    public float maxAngleLOX = 360.0f;
    [Range(0, 360)]
    public float startAngleLOX = 0f;

    public GameObject needle_Fuel;
    public float maxAngleF = 360.0f;
    [Range(0, 360)]
    public float startAngleF = 0f;

    private Quaternion m_OriginalRotationLOX;
    private Quaternion m_OriginalRotationFuel;

    public float _AmountToWander = 0.5F;
    private float _rotationAngleF;
    private float _rotationAngleLOX;

    [Range(0, 1)]
    public float wanderspeed = 1.0f;
    private float startFuel = 100f;

    private void Start()
    {
        m_OriginalRotationFuel = needle_Fuel.transform.localRotation;
        m_OriginalRotationLOX = needle_LOX.transform.localRotation;
    }


    private void FixedUpdate()
    {
        float fuelLevel = (startFuel - Time.deltaTime) / startFuel; // burning fuel over time as a cheap fix for a true fuel method
        float wander = Time.time * wanderspeed;
        _rotationAngleF = UnityEngine.Random.Range(_AmountToWander, -_AmountToWander) + (startAngleF * fuelLevel);
        Quaternion newQuat = m_OriginalRotationFuel * Quaternion.Euler(0, _rotationAngleF, 0);
        needle_Fuel.transform.localRotation = Quaternion.Lerp(m_OriginalRotationFuel, newQuat, wander);

        _rotationAngleLOX = UnityEngine.Random.Range(_AmountToWander, -_AmountToWander) + (startAngleLOX * fuelLevel);
        Quaternion newQuat2 = m_OriginalRotationLOX * Quaternion.Euler(0, -_rotationAngleLOX, 0);
        needle_LOX.transform.localRotation = Quaternion.Lerp(m_OriginalRotationLOX, newQuat2, wander);
    }
}


The Velocity Gauge Script

Note: Change the line:
_shipVel = shipController.VelocityMain;

to
_shipVel = _thisShip.GetComponent<Rigidbody>().velocity

then delete the MyFlightController junk that you dont need....

Can probably drop the IEnumerator "waitforinit" as well

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Instru_Velocity : MonoBehaviour {

    public GameObject _thisShip;

    public GameObject _Needle;

    [Tooltip("Angle at which the Needle with start/rest")]
    [Range(0, 360)]
    public float startAngle = 0f;

    [Tooltip("Angle range for the Needle")]
    [Range(0, 360)]
    public float maxAngle = 360.0f;

    public MyFlightController shipController;
    private bool rdy = false;
    private bool isBelowSeaLevel;
    private Quaternion m_NeedleOriginalRotation;

    private float _rot;
    private float _shipVel;

    private void Start()
    {
        m_NeedleOriginalRotation = _Needle.transform.localRotation;
        StartCoroutine("WaitforInit");
    }

    private IEnumerator WaitforInit()
    {
        yield return new WaitUntil(() => _thisShip.GetComponent<MyFlightController>() != null);
        shipController = _thisShip.GetComponent<MyFlightController>();
        rdy = true;
    }

    private void Update()
    {
        if (!rdy)
        {
            Debug.Log("NOT RDY");
            return;
        }

        _shipVel = shipController.VelocityMain;
        _rot = maxAngle * ( _shipVel * .001f); // meter maxes out at 1000 m/s.. get percentage of that total by ( _v / 1000.0f ) aka ( _v* .001f ) for optimization
        _rot = Mathf.Clamp(_rot, 0.0f, maxAngle); 
        _Needle.transform.localRotation = m_NeedleOriginalRotation * Quaternion.Euler(0, _rot, 0);
    }
}
Thanked by 1konman

Comments

  • edited
    If you are planning on taking this project further and further, you might want to look at how you design and structure your classes. Your gauges seem to lend themselves to at least some form of inheritance, as you yourself say
    This is a Single Needle Version of the next script "Fuel Gauge"
    .

    Also you might want to look into SOLID principles, even if you don't follow it to a tee.
    Separating concerns and making your gauges have a single responsibility, will allow you to be much more flexible and repeat less code.

    For example, instead of hard-coding a gauge to be velocity only (since it gets the value from the rigidbody or in your case the shipController), you could have it use a float value, where that comes from, does not matter.

    Then you either have that float set by some event.
    Or use inheritance to at least reduce repetition.
    So have a base class like
    virtual class BaseGauge
    with something like
    virtual float GetNeedleValue()
    which just returns a constant float (set in inspector perhaps).
    You then inherit from and
    override float GetNeedleValue()
    in a more specific class like
    VelocityGauge
    , that uses a referenced rigidbody's velocity to return the float.

    There are likely even better ways of doing this, but this was just as one idea I had.
    You will eventually need to think of things like this, since as the game gets bigger, it will become harder and harder to introduce changes (in the game in general, not just with gauges), as you will currently need to go make changes in many places, which is not fun.

    On the other hand, please ignore all this if you feel you still want to prototype and just push out features. Since it does get easy to get bogged down on designing a clean system, and deciding what to make modular etc. So if that is the case just keep going, and make the game you wish to make.
    Thanked by 1Moga
  • @vince Thank you again! Yeah my attitude towards the elegance of the code has been as you describe.
    On the other hand, please ignore all this if you feel you still want to prototype and just push out features. Since it does get easy to get bogged down on designing a clean system, and deciding what to make modular etc. So if that is the case just keep going, and make the game you wish to make.
    However, your response is prompting me to think critically and to be really honest, sometimes I just don't know how.

    Got any recommendations for SOLID principle resources?
  • You can check out this link from UNITE Austin.

    It covers it in a Unity approach. However reading up on SOLID in general helps a lot, just to keep it in the back of your mind.
    Thanked by 2konman Moga
  • @vince just finished up a script set that is using inheritance and composition together! Thanks for the nudge! Ill have to re-post these scripts after another pass and get your take =)
    Thanked by 1vince
Sign In or Register to comment.