Quadcopter - a few issues

I started this little project a night ago, and have made great progress I think so far. This is my first time fully creating a mesh in blender, texturing, animating, and integrating it into unity. I figured a little quadcopter would be fun :slight_smile:

I am running into issues, but I will get to that at the bottom. Please excuse the added tooltips and what have you, I was merely messing around with attributes. The ranges however come into use nicely I suppose.

Here is the full script attached to my Quadcopter.

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


public class Quadcopter : MonoBehaviour
{
    public float blade_curSpeed;
    [Tooltip("Max:20")]
    [Range(0f,20f)]
    public float blade_acceleration = 1f;
    [Tooltip("Max:50")]
    [Range(0f,50f)]
    public float blade_maxSpeed = 20f;
    [Tooltip("Max:10")]
    [Range(0f,10f)]
    public float blade_decceleration = 1f;
    //**/***********//*********//*********
    [Tooltip("Max:50")]
    [Range(0f,50f)]
    public float quad_maxSpeed = 20f;
    [Tooltip("Max:20")]
    [Range(0f,20)]
    public float quad_acceleraion = 1f;
    [Tooltip("Max:10")]
    [Range(0f,10)]
    public float quad_decceleration = 1.5f;
    public float quad_curVel;
    public float quad_curHeight;

    private float minLockHeight = 1f;
    public bool canAltLock;
    public bool altLockEnable;
    private Rigidbody quad_Rb;

    void Start()
    {
        quad_Rb = GetComponent<Rigidbody>();
        altLockEnable = false;
    }



    void Update()
    {
        quad_curHeight = transform.position.y;

        if (transform.position.y >= minLockHeight)
        {
            if (Input.GetKeyDown (KeyCode.L))
            {
                altLockEnable = !altLockEnable;
            }
        }

   

        BladeMotor ();
        UpwardsForce ();
        AltitudeLock ();
    }

    void AltitudeLock()
    {
            if (altLockEnable)
            {
                quad_Rb.constraints = RigidbodyConstraints.FreezePositionY;
                blade_curSpeed = 20f;
            }
            else if (altLockEnable == false)
            {
                quad_Rb.constraints = RigidbodyConstraints.None;
            }
    }

    void UpwardsForce()
    {
        if (Input.GetKey (KeyCode.K))
        {
           
            quad_curVel += quad_acceleraion * Time.deltaTime;
        }
        else
        {
            quad_curVel -= quad_acceleraion * quad_decceleration * Time.deltaTime;

        }

        // Speed clamps
        if (quad_curVel >= quad_maxSpeed)
        {
            quad_curVel = quad_maxSpeed;
        }

        if (quad_curVel <= 0)
        {
            quad_curVel = 0;
        }

        Vector3 moveForce = Vector3.up;
        quad_Rb.AddForce (moveForce * quad_curVel);
    }

    void BladeMotor()
    {
        foreach (Transform child in transform)
        {
            if (child.tag == "Blade")
            {
                if (Input.GetKey (KeyCode.K))
                {
                    blade_curSpeed += blade_acceleration * Time.deltaTime;
                }

                else
                {
                    blade_curSpeed -= blade_acceleration * blade_decceleration * Time.deltaTime;
                }
                // So we dont get acceleration past set max speed
                if (blade_curSpeed > blade_maxSpeed)
                {
                    blade_curSpeed = blade_maxSpeed;
                }
                // Same for deccel
                if (blade_curSpeed <= 0)
                {
                    blade_curSpeed = 0;               
                }

                Vector3 tempRot = new Vector3 (0, 0, -90);
                child.transform.Rotate (tempRot * blade_curSpeed * Time.deltaTime);
            }
        }
    }



}

For the most part, I am proud of my progress so far. Currently it only has an upwards force being applied.

I have 2 main issues really, and I feel like they arent that confusing. I’ve been working on this all day and Im just burnt out after lol.

1st issue being the blades. They are suppose to gain rotation speed and match the upwards force to simulate real quadcopter physics. This works perfectly. The issue is when I am trying to implement my altitude control.

I am trying to make a function to hold the current altitude while also preserving the blades rotation. A “hover” effect if you will. Locking its position on the Y axis is working, but the blades are not. Im cheating with the current code and im just setting it to its max speed when pressing the lock (“L”) button. Obviously this is not what Id like. Im trying to I guess, save the current speed of the blades the moment I hit L, then continue to add until im at the max. But I really dont know how to get the value of the current speed at that very frame while in update. Really need some help with this.

2nd issue is related to the first, in just preserving values. When I am the altitude lock mode, and press L again to get out of it, I just fall to the ground. I need to preserve that force value and decrease it so it falls down as it would in real life.

Without the altitude lock, all works well. Releasing K brings be down with deceleration as expected irl, same with upwards acceleration.

Can anyone help? Thanks

here is my 1 hour of work on your script. it’s not even close to being right. but it’s neat hover, with and without using the L key

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


public class Quadcopter : MonoBehaviour
{
    public float blade_curSpeed;
    [Tooltip("Max:20")]
    [Range(0f, 20f)]
    public float blade_acceleration = 1f;
    [Tooltip("Max:50")]
    [Range(0f, 50f)]
    public float blade_maxSpeed = 20f;
    [Tooltip("Max:10")]
    [Range(0f, 10f)]
    public float blade_decceleration = 1f;
    //**/***********//*********//*********
    [Tooltip("Max:50")]
    [Range(0f, 50f)]
    public float quad_maxSpeed = 20f;
    [Tooltip("Max:20")]
    [Range(0f, 20)]
    public float quad_acceleraion = 1f;
    [Tooltip("Max:10")]
    [Range(0f, 10)]
    public float quad_decceleration = 1.5f;
    public float quad_curVel;
    public float quad_curHeight;

    private float minLockHeight = 1f;
    public bool canAltLock;
    public bool altLockEnable;
    private Rigidbody quad_Rb;

    void Start()
    {
        quad_Rb = GetComponent<Rigidbody>();
        altLockEnable = false;
    }



    void Update()
    {
        quad_curHeight = transform.position.y;

        if (transform.position.y >= minLockHeight)
        {
            if (Input.GetKeyDown(KeyCode.L))
            {
                altLockEnable = !altLockEnable;
                Debug.Log(altLockEnable);
            }
        }



        BladeMotor();
        UpwardsForce();
        AltitudeLock();
    }

    void AltitudeLock()
    {
        if (altLockEnable)
        {
            //quad_Rb.constraints = RigidbodyConstraints.FreezePositionY;
            quad_Rb.velocity = new Vector3(0,Random.Range(-0.2f, 0.2f),0);
            blade_curSpeed = 20f;
        }
        else if (altLockEnable == false)
        {
            quad_Rb.constraints = RigidbodyConstraints.None;
        }
    }

    void UpwardsForce()
    {
        if (Input.GetKey(KeyCode.K))
        {

            quad_curVel += quad_Rb.velocity.y + quad_acceleraion * Time.deltaTime;
        }
        else
        {
            quad_curVel -= quad_Rb.velocity.y + quad_decceleration * Time.deltaTime;

        }

        // Speed clamps
        if (quad_curVel >= quad_maxSpeed)
        {
            quad_curVel = quad_maxSpeed;
        }

        if (quad_curVel <= 0)
        {
            quad_curVel = 0;
        }

        Vector3 moveForce = Vector3.up;
        quad_Rb.AddForce(moveForce * quad_curVel);
        //Debug.Log("force : " + quad_Rb.velocity);
    }

    void BladeMotor()
    {
        foreach (Transform child in transform)
        {
            if (child.tag == "Blade")
            {
                if (Input.GetKey(KeyCode.K))
                {
                    blade_curSpeed += blade_acceleration * Time.deltaTime;
                }

                else
                {
                    blade_curSpeed -= blade_acceleration * blade_decceleration * Time.deltaTime;
                }
                // So we dont get acceleration past set max speed
                if (blade_curSpeed > blade_maxSpeed)
                {
                    blade_curSpeed = blade_maxSpeed;
                }
                // Same for deccel
                if (blade_curSpeed <= 0)
                {
                    blade_curSpeed = 0;
                }

                Vector3 tempRot = new Vector3(0, 0, -90);
                child.transform.Rotate(tempRot * blade_curSpeed * Time.deltaTime);
            }
        }
    }



}

Thanks for the revision! I see youve made things a little more easy to read and understand while taking away useless variable locations :slight_smile:

I especially appreciate the hover logic! That was gonna be the next thing I figured out after blade rotation hah.

I havent had time to test this yet, but does it cover my 2nd issue? From what I am seeing in your revision, altering the rb’s velocity may seem to fix it… but im just not at my work station yet this morning :b

Thanks for spending the time to help me tho, I very much appreciate it.

this does not fix the issue with the blade speed matching the height. I think you need logic based on velocity.y.
press key “what ever key you want” to turn on quadcopter. this should enable / disable the blades spinning. and then add / subtract blade speed based on the velocity.y float.

something like this.
FYI, not tested

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Quadcopter : MonoBehaviour
{
    public float blade_curSpeed;
    [Tooltip("Max:20")]
    [Range(0f, 20f)]
    public float blade_acceleration = 1f;
    [Tooltip("Max:50")]
    [Range(0f, 50f)]
    public float blade_maxSpeed = 20f;
    [Tooltip("Max:10")]
    [Range(0f, 10f)]
    public float blade_decceleration = 1f;
    //**/***********//*********//*********
    [Tooltip("Max:50")]
    [Range(0f, 50f)]
    public float quad_maxSpeed = 20f;
    [Tooltip("Max:20")]
    [Range(0f, 20)]
    public float quad_acceleraion = 1f;
    [Tooltip("Max:10")]
    [Range(0f, 10)]
    public float quad_decceleration = 1.5f;
    public float quad_curVel;
    public float quad_curHeight;
    private float minLockHeight = 1f;
    public bool canAltLock;
    public bool altLockEnable;
    private Rigidbody quad_Rb;
    private bool powerIsOn = false;
    void Start()
    {
        quad_Rb = GetComponent<Rigidbody>();
        altLockEnable = false;
    }
    void Update()
    {
        quad_curHeight = transform.position.y;
        if (Input.GetKeyDown(KeyCode.P))
        {
            altLockEnable = !altLockEnable;
            Debug.Log(altLockEnable);
        }

        if (transform.position.y >= minLockHeight)
        {
            if (Input.GetKeyDown(KeyCode.L))
            {
                powerIsOn = !powerIsOn;
                Debug.Log("Power " + powerIsOn);
            }
        }
        BladeMotor();
        UpwardsForce();
        AltitudeLock();
    }
    void AltitudeLock()
    {
        if (altLockEnable)
        {
            //quad_Rb.constraints = RigidbodyConstraints.FreezePositionY;
            quad_Rb.velocity = new Vector3(0,Random.Range(-0.2f, 0.2f),0);
            blade_curSpeed = 20f;
        }
        else if (altLockEnable == false)
        {
            quad_Rb.constraints = RigidbodyConstraints.None;
        }
    }
    void UpwardsForce()
    {
        if (Input.GetKey(KeyCode.K))
        {
            quad_curVel += quad_Rb.velocity.y + quad_acceleraion * Time.deltaTime;
        }
        else
        {
            quad_curVel -= quad_Rb.velocity.y + quad_decceleration * Time.deltaTime;
        }
        // Speed clamps
        if (quad_curVel >= quad_maxSpeed)
        {
            quad_curVel = quad_maxSpeed;
        }
        if (quad_curVel <= 0)
        {
            quad_curVel = 0;
        }
        Vector3 moveForce = Vector3.up;
        quad_Rb.AddForce(moveForce * quad_curVel);
        //Debug.Log("force : " + quad_Rb.velocity);
    }
    void BladeMotor()
    {
        foreach (Transform child in transform)
        {
            if (child.tag == "Blade")
            {
                if (powerIsOn)
                {
                    blade_curSpeed = blade_maxSpeed;
                }
                else
                {
                    blade_curSpeed = 0;
                }

                // this should be changed to velocity.y
                if (quad_Rb.velocity.y > 0)
                {
                    blade_curSpeed = blade_maxSpeed + quad_Rb.velocity.y;
                }else if(quad_Rb.velocity.y < 0)
                {
                    blade_curSpeed = blade_maxSpeed - quad_Rb.velocity.y;
                }

                // Same for deccel
                if (blade_curSpeed <= 0)
                {
                    blade_curSpeed = 0;
                }
                Vector3 tempRot = new Vector3(0, 0, -90);
                child.transform.Rotate(tempRot * blade_curSpeed * Time.deltaTime);
            }
        }
    }
}