Monday, November 21, 2022
HomeGame Developmentunity - 6DoF digicam management with a toggleable gimbal/horizon line lock and...

unity – 6DoF digicam management with a toggleable gimbal/horizon line lock and auto-upright button


Demo GIF

I’ve a clean 6DoF controller from following a tutorial (that is the tutorial) and tweaked it to be precisely what I would like with a couple of exceptions.

I discovered myself wanting the flexibility to lock the horizon line by urgent a toggle button so whereas the participant is freely rotating across the horizon stays degree till the lock is disabled.

I might additionally wish to have a button that easily rotates the horizon to be degree with the Ship object/digicam however preserve the yaw and pitch the identical. I am undecided how it could work however I would like this button to easily easily upright the Ship when the button is pressed as soon as and have the horizon lock be a separate non-obligatory function.

I don’t know the place to even begin on the mathematics/logic for these two options however I’ve the buttons and features mapped already hoping I’d simply gleam somebody’s smarter code and simply having it magically work ultimately. I’ve a sense there’s a greater manner of going about this than guessing or trial and error haha.

The complete script for the Ship object is self-contained and I will put it right here together with some photographs and GIFs of assorted hopefully helpful particulars.

As an apart, I am certain there is a easy answer I am overlooking however the ship does roll when colliding with different objects (spherical collision mesh). Is there a strategy to both disable it or have much less friction?

utilizing System.Collections;
utilizing System.Collections.Generic;
utilizing UnityEngine;
utilizing UnityEngine.InputSystem;

[RequireComponent (typeof(Rigidbody))]

public class Ship : MonoBehaviour
{
    // Parameters
    [Header("=== Ship Movement Settings ===")]
    [SerializeField]
    non-public float pitchTorque = 500f;
    [SerializeField]
    non-public float yawTorque = 1000f;
    [SerializeField]
    non-public float rollTorque = 1000f;
    [SerializeField]
    non-public float thrust = 100f;
    [SerializeField]
    non-public float strafeThrust = 50f;
    [SerializeField]
    non-public float verticalThrust = 50f;
    public bool horizonLock = false;

    [Header("=== Boost Settings ===")]
    [SerializeField]
    non-public float boostMultiplier = 5f;

    [Header("=== Thrust Reduction Settings ===")]
    [SerializeField]
    non-public float drag = 1f;
    [SerializeField]
    non-public float angularDrag = 0.5f;
    [SerializeField, Range(0.001f, 0.999f)]
    non-public float thrustGlideReduction = 0.9f;
    [SerializeField, Range(0.001f, 0.999f)]
    non-public float strafeGlideReduction = 0.1f;
    [SerializeField, Range(0.001f, 0.999f)]
    non-public float verticalGlideReduction = 0.1f;


    // Variables
    Rigidbody rb;
    float glide = 0f;
    float strafeGlide = 0f;
    float verticalGlide = 0f;
    bool boosting = false;
    bool altMove = false;
    bool altRoll = false;
    bool cease = false;
    bool autoUpright = false;

    // Enter Values
    non-public float thrust1D;
    non-public float strafe1D;
    non-public float vertical1D;
    non-public float roll1D;
    non-public Vector2 pitchYaw;


    // Begin is known as earlier than the primary body replace
    void Begin()
    {
        rb = GetComponent<Rigidbody>();
    }

    // Replace is known as as soon as per body
    void FixedUpdate()
    {
        HandleMovement();
    }


    void HandleMovement()
    {
        /* The explanation for all of the altRoll and altMove statements is to have alternate momentary
         * manner of shifting and rolling the ship.
         * 
         * AltMove shifts horizontal and ahead/backward motion inputs to vertical/horizontal motion.
         * It additionally shifts vertical motion inputs to ahead/backward motion.
         * 
         * AltRoll shifts the yaw/pitch motion inputs to roll/pitch.
         * It additionally maps roll inputs to yaw for comfort.
         */


        // Roll
        if(!altRoll) rb.AddRelativeTorque(Vector3.again * roll1D * rollTorque * Time.deltaTime);
        else rb.AddRelativeTorque(Vector3.again * Mathf.Clamp(pitchYaw.x, -1f, 1f) * rollTorque * Time.deltaTime);

        // Pitch
        rb.AddRelativeTorque(Vector3.proper * Mathf.Clamp(-pitchYaw.y, -1f, 1f) * pitchTorque * Time.deltaTime);

        // Yaw
        if (!altRoll) rb.AddRelativeTorque(Vector3.up * Mathf.Clamp(pitchYaw.x, -1f, 1f) * yawTorque * Time.deltaTime);
        else rb.AddRelativeTorque(Vector3.up * roll1D * yawTorque * Time.deltaTime);


        // Thrust
        if (!altMove && (thrust1D > 0.1f || thrust1D < -0.1f))
        {
            float currentThrust;
            if (boosting) currentThrust = thrust * boostMultiplier;
            else currentThrust = thrust;

            rb.AddRelativeForce(Vector3.ahead * thrust1D * currentThrust * Time.deltaTime);
            glide = thrust;
        }
        else if(altMove && (vertical1D > 0.1f || vertical1D < -0.1f))
        {
            float currentThrust;
            if (boosting) currentThrust = thrust * boostMultiplier;
            else currentThrust = thrust;

            rb.AddRelativeForce(Vector3.ahead * vertical1D * currentThrust * Time.deltaTime);
            glide = thrust;
        }
        else
        {
            rb.AddRelativeForce(Vector3.ahead * glide * Time.deltaTime);
            glide *= thrustGlideReduction;
        }


        // Strafe
        if (strafe1D > 0.1f || strafe1D < -0.1f)
        {
            float currentThrust;
            if (boosting) currentThrust = thrust * boostMultiplier;
            else currentThrust = thrust;

            rb.AddRelativeForce(Vector3.proper * strafe1D * currentThrust * Time.deltaTime);
            strafeGlide = strafe1D * strafeThrust;
        }
        else
        {
            rb.AddRelativeForce(Vector3.proper * strafeGlide * Time.deltaTime);
            strafeGlide *= strafeGlideReduction;
        }


        // Vertical
        if (!altMove && (vertical1D > 0.1f || vertical1D < -0.1f))
        {
            float currentThrust;
            if (boosting) currentThrust = thrust * boostMultiplier;
            else currentThrust = thrust;

            rb.AddRelativeForce(Vector3.up * vertical1D * currentThrust * Time.deltaTime);
            verticalGlide = vertical1D * verticalThrust;
        }
        else if (altMove && (thrust1D > 0.1f || thrust1D < -0.1f))
        {
            float currentThrust;
            if (boosting) currentThrust = thrust * boostMultiplier;
            else currentThrust = thrust;

            rb.AddRelativeForce(Vector3.up * thrust1D * currentThrust * Time.deltaTime);
            verticalGlide = thrust1D * verticalThrust;
        }
        else
        {
            rb.AddRelativeForce(Vector3.up * verticalGlide * Time.deltaTime);
            verticalGlide *= verticalGlideReduction;
        }

        // What I name the "cease on a dime" button. Momentarily will increase drag to freeze the ship in place.
        if (cease)
        {
            rb.drag = 50;
            rb.angularDrag = 50;
        }
        else
        {
            rb.drag = drag;
            rb.angularDrag = angularDrag;
        }
    }



    // Enter handlers
    #area Enter Strategies

    public void OnThrust(InputAction.CallbackContext context)
    {
        thrust1D = context.ReadValue<float>();
    }

    public void OnStrafe(InputAction.CallbackContext context)
    {
        strafe1D = context.ReadValue<float>();
    }

    public void OnVertical(InputAction.CallbackContext context)
    {
        vertical1D = context.ReadValue<float>();
    }

    public void OnRoll(InputAction.CallbackContext context)
    {
        roll1D = context.ReadValue<float>();
    }

    public void OnPitchYaw(InputAction.CallbackContext context)
    {
        pitchYaw = context.ReadValue<Vector2>();
    }

    public void OnBoost(InputAction.CallbackContext context)
    {
        boosting = context.carried out;
    }

    public void OnAltMove(InputAction.CallbackContext context)
    {
        altMove = context.carried out;
    }

    public void OnAltRoll(InputAction.CallbackContext context)
    {
        altRoll = context.carried out;
    }

    public void OnStop(InputAction.CallbackContext context)
    {
        cease = context.carried out;
    }

    public void OnHorizonLock(InputAction.CallbackContext context)
    {
        horizonLock = !horizonLock;
    }

    public void OnAutoUpright(InputAction.CallbackContext context)
    {
        autoUpright = context.carried out;
    }

    #endregion
}

Inspector Window for the Ship object.

Inspector window for ship

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -
Google search engine

Most Popular

Recent Comments