[SOLVED] Rotation using lerp

Hi @everyone
I am rotating enemy along players direction angle. But it seems resetting at some point. usually in the corners. How can I fix this issue.


Below code I used for rotation

TestDynamicMovement.prototype.attackState = function (dt) {
    //console.log("Attacking");

    let playerPosition = this.playerEntity.getPosition().clone();
    let enemyPosition = this.entity.getPosition().clone();

    let direction = playerPosition.sub(enemyPosition).normalize();
    let angle = Math.atan2(direction.x, direction.y) * pc.math.RAD_TO_DEG;

    let currentRotation = this.entity.getEulerAngles().clone().z;
    console.log(Math.trunc(angle), Math.trunc(currentRotation))
    let newRotation = pc.math.lerpAngle(currentRotation, -angle, 0.03);//0.02
    this.entity.setEulerAngles(0, 0, newRotation);

    //Attacking player logic
    if (this.canShoot()) {
        this.shoot();
    }
    if (this.playerTooFar()) {
        this.currentState = this.states.CHASE;
    }
};

Thank you

1 Like

@yaustar @Albertos any updates on the above query ?

Sorry, I don’t know what can be the problem. Personally I use different code to rotate smooth to a specific point.

What do you mean with the corners?

The enemy entity has a kinematic rigidbody?

Not exactly the corners when the angle to rotate is say 22 degree then it starts rotating and at some point it goes back to -180 which is specifies in editor

can you tell me what different approach do you use ?

Yes ofcourse, but can you also answer my questions?

Enemy is having dynamic rigidbody

You can’t use setEulerAngles() on an entity with a dynamic rigidbody. Only the visual entity is rotating, but the rigidbody is not. At some point the rigidbody is trying to reset this rotation. Maybe you can try to use a kinematic rigidbody or using something like teleport() instead of setEulerAngles().

Okay thank you

But can we use setRotation by making use of pc.Quat() because for player entity I did rotation using Quaternion angle and movement using teleport

As far as I know, you also can’t use setRotation() on a dynamic rigidbody. You don’t see any issues on the player entity?

No I didn’t find any issue in the movement of player entity .Also I am moving player entity based on mouse cursor

Below code I used for the movement of player entity

MouseControl.prototype.update = function (dt) {
    if (this.pointerLocked) {
        // console.log("init cam pos :", this.cameraEntity.getPosition())
        this.camera.worldToScreen(this.entity.position, this.screenPos);
        this.screenPos.z = 0;
        this.directionToMouse.sub2(this.mousePos, this.screenPos);
        this.directionToMouse.y *= -1;

        var angle = Math.atan2(this.directionToMouse.x, this.directionToMouse.y) * pc.math.RAD_TO_DEG;
        var targetRotation = this.targetRotation.clone().setFromEulerAngles(90, 0, 90 - angle);
        var newRotation = this.newRotation.slerp(this.entity.getRotation(), targetRotation, 0.2);// slerp for smooth rotation
        this.entity.setRotation(newRotation);
        this.directionToMouse.normalize().scale(this.movementSpeed);
        this.entity.rigidbody.teleport(this.entity.getPosition().add(this.directionToMouse));

        let cameraPosition = new pc.Vec3();
        cameraPosition.lerp(this.cameraEntity.getPosition().clone(), this.entity.getPosition().clone(), 0.5);
        this.cameraEntity.setPosition(cameraPosition.x, cameraPosition.y, this.cameraEntity.getPosition().clone().z);
        // console.log("cam pos :", this.cameraEntity.getPosition())
    }
}

Below Code I am using for Enemy entity

TestDynamicMovement.prototype.attackState = function () {
    let playerPosition = this.playerEntity.getPosition().clone();
    let enemyPosition = this.entity.getPosition().clone();

    let direction = playerPosition.sub(enemyPosition).normalize();
    let angle = (Math.atan2(direction.x, direction.y) * pc.math.RAD_TO_DEG);
    let currentRotation = this.entity.getRotation().clone();

    let newRotation = new pc.Quat().setFromEulerAngles(0, 0, -angle);
    currentRotation.slerp(currentRotation, newRotation, 0.03)

    console.log(Math.round(angle), currentRotation.z);

    this.entity.setRotation(currentRotation);

    // Attacking player logic
    if (this.canShoot()) {
        this.shoot();
    }
    if (this.playerTooFar()) {
        this.currentState = this.states.CHASE;
    }
};

On line 14 of the player rotation you use teleport(), like I suggested. Maybe you can use the same logic for the enemy rotation.

1 Like
TestDynamicMovement.prototype.attackState = function () {
    let playerPosition = this.playerEntity.getPosition().clone();
    let enemyPosition = this.entity.getPosition().clone();

    let direction = playerPosition.sub(enemyPosition).normalize();
    let angle = (Math.atan2(direction.x, direction.y) * pc.math.RAD_TO_DEG);
    let currentRotation = this.entity.getRotation().clone();

    let newRotation = new pc.Quat().setFromEulerAngles(0, 0, -angle);

    currentRotation.slerp(currentRotation, newRotation, 0.03)


    //this.entity.setRotation(currentRotation);
    this.entity.rigidbody.teleport(enemyPosition, currentRotation)

    // Attacking player logic
    if (this.canShoot()) {
        this.shoot();
    }
    if (this.playerTooFar()) {
        this.currentState = this.states.CHASE;
    }
};

This worked fine @Albertos :smiley: :+1:

1 Like

Great! Thanks for sharing! :ok_hand:

1 Like