Drone Controller in Unity: movement issues with the unity inputSystem

Viewed 168

I'm trying to build a controller for a unity gameobject to move it similary to a normel quadrotor drone. So the drone should be able to ascend and descend by mobing the left stick up and down, turn around by moving the left stick sidewards and move horizontally by using the right stick.

I tried implementing it with the unity inputSystem, but unfortunately, it doesn't really work the way it is supposed to. Movements are mostly not smooth and the rotation causes the horizonzal movement to move in wrong directions.

Here is my code:

    public void OnMove(InputValue inputValue)
    {
        //horizontal movement
        Debug.Log(inputValue.Get());
        Vector3 move = new   Vector3(inputValue.Get<Vector2>().x * 10 * Time.deltaTime, 0, inputValue.Get<Vector2>().y * 1 * Time.deltaTime);
        move = Quaternion.Euler(0, rotation, 0) * move;
        //playerDrone.transform.position += new Vector3(inputValue.Get<Vector2>().x * 10 * Time.deltaTime, 0, inputValue.Get<Vector2>().y * 10 * Time.deltaTime);
        playerDrone.transform.Translate(move, Space.World);
    }

    public void OnClockwiseRotation()
    {
        //rotation of drone clockwise
        playerCam.transform.Rotate(0, 0.5f, 0, Space.World);
        rotation += 0.5f;
    }

    public void OnCounterclockwiseRotation()
    {
        //rotation of drone counterclockwise
        Debug.Log("Rotation");
        playerCam.transform.Rotate(0, -0.5f, 0, Space.World);
        rotation += 0.5f;
    }

    public void OnAscend1()
    {
        //ascend drone
        playerDrone.transform.position += new Vector3(0, 0.1f, 0);
        Debug.Log("Ascend");
    }

    public void OnDescend()
    {
        //descend drone
        Debug.Log("Descend");
        playerDrone.transform.position += new Vector3(0, -0.1f, 0);
    }

Does anyone know why the movement is so problematic with that implementation?

Thanks in advance

1 Answers

There are a few mistakes I'd say

  • Your rotation and your ascending are frame-rate dependent. Here you didn't use Time.deltaTime

  • In both OnClockwiseRotation and OnCounterclockwiseRotation you do

    rotation += 0.5f;
    
  • You are using once playerDrone and another time playerCam .. you should probably stick to one as it sounds like you are only rotating a camera but not the drone.

  • In general I would not hardcode the values into your code but rather expose some class fields so you can adjust the velocities vis the Inspector without having to recompile

You probably would rather do something like

// Adjust these in the Inspector!

// in angle per second
public float rotationSpeed = 45;

// in meter per second
public float ascendingSpeed = 1;
public float forwardSpeed = 1;
public float sidewardsSpeed = 1;

public void OnMove(InputValue inputValue)
{
    // In this case probably not a big deal but in general use getters only once
    var input = inputValue.Get();

    var move = new Vector3(input.x * sidewardsSpeed * Time.deltaTime, 0, input.y * forwardSpeed * Time.deltaTime);
    move = Quaternion.Euler(0, rotation, 0) * move;
    playerDrone.transform.Translate(move, Space.World);
}

public void OnClockwiseRotation()
{
    var angle = rotationSpeed * Time.deltaTime;
    playerDrone.transform.Rotate(0, angle, 0, Space.World);
    rotation += angle;
}

public void OnCounterclockwiseRotation()
{
    var angle = rotationSpeed * Time.deltaTime;
    playerDrone.transform.Rotate(0, -angle, 0, Space.World);
    rotation -= angle;
}

public void OnAscend1()
{
    playerDrone.transform.position += Vector3.up * ascendingSpeed * Time.deltaTime;
}
Related