[SOLVED] How to look at Y axis only?

I try to rotate the weapon of the enemy to the height of the player.
Probably i need this also for a local entity.

rotation
I found a couple C# solutions but translating this to JS gives me not the good result.

If I understand correctly one way to achieve this would be to:

  1. Keep the current rotation angles of the entity in a variable.
  2. Execute lookAt() to have it look at the point in space you are targetting.
  3. Replace any axis angle that you don’t want to change with the previous angles from step 1.

Oke, with the code below the weapon is rotating on the good axis but not with the good angle…

// update code called every frame
LookAtplayer.prototype.update = function(dt) {
    var eulerAngleX = this.entity.getEulerAngles().x;
    var eulerAngleY = this.entity.getEulerAngles().y;
    var eulerAngleZ = this.entity.getEulerAngles().z;
    this.entity.lookAt(player.getPosition());
    this.entity.setEulerAngles(eulerAngleX, this.entity.getEulerAngles().y, eulerAngleZ);
};

I know this might not be easy in this case, but will help to build a working code if you can provide an example.

Oke i create a sample project and set the rotation of the weapon the same as the weapon in my game. So in the sample you get the same result as i get in my game right now. (If you reset the rotation of the weapon to 0,0,0 then also the result is wrong).

Please check te movement script for the controls.

https://playcanvas.com/editor/scene/867937

Right, now I understand what you need. You can more easily and accurately calculate the angle between the two entities in a single axis.

I’ve reworked your example:

https://playcanvas.com/editor/scene/868902

Next problem is the local rotation. I played with the angles but I can’t figur out wich angle i have to change to get the good rotation on the weapon that is on the enemy.

I have update my sample project with the enemy itself. Maybe you see wich rotation i have to change.

https://playcanvas.com/editor/scene/867937

Maybe this test project of mine will be useful to look at. Right-click and drag to move the “guns” around and you see that they both keep pointing at the cone.

https://playcanvas.com/project/612692/overview/gun-project

2 Likes

Hey @albertos, change your last two lines to this:

    var angleToPlayer = angleInRadians * pc.math.RAD_TO_DEG;

    this.weapon.setEulerAngles(-angleToPlayer, this.angles.y, this.angles.z);

Since the weapon is a child to a parent element, and we are calculating world space angles it isn’t always straightforward to find the right axis.

Luckily we only have 3 of them, so with some trial and error you can get it at the end.

1 Like

I still had to make a few extra adjustments for the real game, but now it works as I had in mind! Thanks everyone!

1 Like

Can we do this smoothly?

Sure use a custom tween, take a look at how the lookAt method was implemented here to be smooth:

I have already tried to use a tween in the update before, but without success.

What should I change to use the method below?

        this.rotateTime += dt; 
        var percent = this.rotateTime / 5;

        var original_rotation = new pc.Quat();
        var final_rotation = new pc.Quat();

        original_rotation.copy(this.entity.getRotation());
        this.entity.lookAt(this.rotateTowardThis); 
        final_rotation.copy(this.entity.getRotation());

        this.entity.setRotation(original_rotation);

        var new_rotation = this.rotateTowards(original_rotation, final_rotation, 0.05);

        this.entity.setRotation(new_rotation);

        if (percent > 0.05){
            this.rotateTowardThis = null;
            this.rotateTime = 0;
        }

I might be off here, but I think the tween library works with local transformations. Have you tried .getLocalRotation()?

    // --- stop any active tween
    if( this.tween ){
        this.tween.stop();
        this.tween = undefined;
    }
    
    // --- initialize the tween with a new target
    this.lookTo.copy(this.player.getPosition());
    
    this.tween = this.app
    .tween(this.lookFrom)
    .to(this.lookTo, 2, pc.SineInOut)
    .on('update', function () {

        this.weapon.lookAt(this.lookFrom);

    }.bind(this) )
    .start();

I dont’t see where i have to get or set the (local) rotations.

Hey @albertos,

You shouldn’t be using the lookAt method, that was just an example on how to tween a custom value. You should be using something like this, not tested so if it doesn’t work try to setup a sample project to help you out:

    var angleToPlayer = angleInRadians * pc.math.RAD_TO_DEG;

    // --- stop any active tween
    if( this.tween ){
        this.tween.stop();
        this.tween = undefined;
    }
    
    // --- initialize the tween with a new target
    this.lookFrom.copy(this.player.getEulerAngles());
    this.lookTo.set(-angleToPlayer, this.lookFrom.y, this.lookFrom.z);
    
    this.tween = this.app
    .tween(this.lookFrom)
    .to(this.lookTo, 2, pc.SineInOut)
    .on('update', function () {

        this.weapon.setEulerAngles(this.lookFrom);

    }.bind(this) )
    .start();

You could also use a getLocalRotation tween as @LeXXik suggests, but given the different world vs local axises that you use might not be easy to setup and get right.

When i use this example code, in my game the weapon
disappears and in the example project (link below) there is nothing happening…

https://playcanvas.com/editor/scene/867937

Note: Because the player moves smoothly in the example project, it seems to be useless, but in the game itself the player moves abruptly.

Ah no, you can’t have a tween inside your update loop. It will start/stop every frame so ultimately it will always be stopped at the initial value.

Now this requires different thinking, you need to transfer your logic from the update method, to actually start when the object has finished moving? Or something similar depending on your gameplay.

Something like this:

https://playcanvas.com/editor/scene/871790

Okay, I understand. However, in the game the weapon disappears when I use the tween. Any idea what this can cause?

If it doesn’t render, then debug your vector most likely a factor (x,y,z) is undefined or NaN and that breaks all translations.