Daniel Lip
Daniel Lip

Reputation: 11319

Why when using lerp to rotate slowly it's not rotating all the time and if it does it's rotating very fast no matter what speed value is given?

In the start :

void Start()
{
ControlPanel.KeyPressed += OnKeyPressed;
}

In the event OnKeyPressed :

private void OnKeyPressed(PressedKeyCode[] obj)
    {
        float tempY = 0;
        float tempX = 0;

        // stable forward
        if (hMove.y > 0)
            tempY = - Time.fixedDeltaTime;
        else
            if (hMove.y < 0)
                tempY = Time.fixedDeltaTime;

        // stable lurn
        if (hMove.x > 0)
            tempX = -Time.fixedDeltaTime;
        else
            if (hMove.x < 0)
                tempX = Time.fixedDeltaTime;


        foreach (var pressedKeyCode in obj)
        {
            switch (pressedKeyCode)
            {
                case PressedKeyCode.SpeedUpPressed:

                    EngineForce += 0.1f;
                    break;
                case PressedKeyCode.SpeedDownPressed:

                    EngineForce -= 0.12f;
                    if (EngineForce < 0) EngineForce = 0;
                    break;

                case PressedKeyCode.ForwardPressed:

                    if (IsOnGround) break;
                    tempY = Time.fixedDeltaTime;
                    break;
                case PressedKeyCode.BackPressed:

                    if (IsOnGround) break;
                    tempY = -Time.fixedDeltaTime;
                    break;
                case PressedKeyCode.LeftPressed:

                    if (IsOnGround) break;
                    tempX = -Time.fixedDeltaTime;
                    break;
                case PressedKeyCode.RightPressed:

                    if (IsOnGround) break;
                    tempX = Time.fixedDeltaTime;
                    break;
                case PressedKeyCode.TurnRightPressed:
                    {
                        if (IsOnGround) break;
                        var force = (turnForcePercent - Mathf.Abs(hMove.y)) * HelicopterModel.mass;
                        HelicopterModel.AddRelativeTorque(0f, force, 0);
                    }
                    break;
                case PressedKeyCode.TurnLeftPressed:
                    {
                        if (IsOnGround) break;

                        var force = -(turnForcePercent - Mathf.Abs(hMove.y)) * HelicopterModel.mass;
                        HelicopterModel.AddRelativeTorque(0f, force, 0);
                    }
                    break;
                case PressedKeyCode.BackToBase:
                    {
                        Vector3 direction = helicopterPlatform.transform.position - transform.position;
                        Quaternion toRotation = Quaternion.FromToRotation(transform.forward, direction);
                        transform.rotation = Quaternion.Lerp(transform.rotation, toRotation, lookAtSpeed * Time.time);

                        //transform.LookAt(helicopterPlatform.transform);
                    }
                    break;
            }
        }

        hMove.x += tempX;
        hMove.x = Mathf.Clamp(hMove.x, -1, 1);

        hMove.y += tempY;
        hMove.y = Mathf.Clamp(hMove.y, -1, 1);

    }

I added the last part :

case PressedKeyCode.BackToBase:
                    {
                        Vector3 direction = helicopterPlatform.transform.position - transform.position;
                        Quaternion toRotation = Quaternion.FromToRotation(transform.forward, direction);
                        transform.rotation = Quaternion.Lerp(transform.rotation, toRotation, lookAtSpeed * Time.time);

                        //transform.LookAt(helicopterPlatform.transform);
                    }
                    break;

When I used LookAt it was working fine but the rotation was a bit too fast, This is how I used the LookAt:

transform.LookAt(helicopterPlatform.transform);

Then I decided to use the direction , toRotation and the Quaternion.Lerp but now when I press the key code B that's the key code for backtobase it's making the object(helicopter) to rotate and then rotate back the direction it was facing and I need to press many times on B to make it rotate facing the helicopterPlatform.

This is a link for the complete script a bit long so I'm not sure if to put it in my question so I uploaded it to pastebin.com : https://pastebin.com/YDfbVkH6

Upvotes: 0

Views: 273

Answers (1)

Remy
Remy

Reputation: 5163

The t value of Lerp is not a speed value, rather it is the progress between point A and B

From the docs on Lerp:

t: Value used to interpolate between a and b.

This means that if you got the following code

 Quaternion.Lerp(transform.rotation, toRotation, t);

when t = 0 the lerp will return whatever is stored in transform.rotation and when t = 1 it will return whatever is in toRotation, t = 0.5f would return whatever is right in between these values and so on for any value between 0 and 1.

Time.time is stated as the following from the docs:

The time at the beginning of this frame (Read Only). This is the time in seconds since the start of the game.

So what you are essentially doing right now is:

transform.rotation = Quaternion.Lerp(transform.rotation, toRotation, lookAtSpeed * time since the start of the game);

as you can see after the scene has run for a couple of seconds (depending on your lookAtSpeed) this value will quickly exceed 1, meaning it will always return toRotation.

What you are looking for is rather to slowly increment the t value from 0 to 1 using a coroutine, looking something like this, which will slowly increment from 0 to 1 based on your lookAtSpeed

internal IEnumerator LerpToPosition()
{
    lookAtSpeed = 2f;
    float t = 0f;
    while (t < 1f)
    {
        t += lookAtSpeed  * Time.deltaTime;
        transform.rotation = Quaternion.Lerp(transform.rotation, toRotation, t);
        yield return waitFrame;
    }
}

Upvotes: 3

Related Questions