In game physics / player rotation and collectibles

Hi, I am working on a game with my housemate, to use as a basis for future projects. We originally had issues with collision, and after asking the people at Play Canvas, we found out that it was because we were using dynamic objects, and kinematic objects, by directly moving / rotating them.

We were moving the player using key presses, set as a kinematic object, and by directly moving the player. This meant that the object never collided with anything and simply went through everything, as the physics was bypassed so to speak.

We now have a player that can move, and collide with other objects. The easiest solution was to apply a force to move the player. :wink:

The only problems we are having now are;

  1. The player can rotate (by directly rotating the player), but is set back to its original orientation when moved. 2) The gem in the level, is a collectible, which upon collision needs to be “destroyed.” The gem simply moves to the center.

Does anyone know how to fix these problems? The project is here:

https://playcanvas.com/project/338195/overview/first-project

Thanks in advance,

Michael

You’re using this.entity.rotateLocal to rotate the tank. This has the same issues as directly translating , i.e. it doesn’t work properly when the entity is a rigidbody being simulated.

You should rigidbody.applyTorque, rigidbody.applyTorqueImpulse to rotate using forces, or set the rigidbody.angularVelocity property.

Dave,

Thank you for the help, this worked nicely, although I should probably have checked the API for that one. The only issue is that the direction of the tank was still around world space, and not local to the player. I have been looking at other projects on here, and they seem to be using a heading, and forward vector.

I have implemented this into my game and this works nicely, except for a few other errors. I can move the player, and if the player turns (by moving around the items in the scene), then the directions are now relative to the player.

My issue now is that everytime I try to turn the player, it dissappears. Looking inside the console window, it says that each value for its position and rotation is now “NaN”. The code I am using is thus:

"
pc.script.create(‘Input’, function (context) {
// Creates a new Input instance
var Input = function (entity) {

    this.entity = entity;
    
    this.Tanks = [];
    
    this.x = new pc.Vec3();
    this.z = new pc.Vec3();
    this.heading = new pc.Vec3();
    
    
    
};

Input.prototype = {
    // Called once after all resources are loaded and before the first update
    initialize: function () {
        
        this.Tanks.push(context.root.findByName("Tank_base"));
        
        console.log(this.Tanks[0].position);
        
    },

    // Called every frame, dt is time in seconds since last update
    update: function (dt) {
        
        var tempC = new pc.Vec3();

        var TempD = new pc.Vec3();

        var rot = new pc.Mat4();
        
        var input;
        
        input = false;

        // Calculate the Tanks heading in the XZ plane
        this.z.copy(this.Tanks[0].forward).scale(-1);
        this.z.y = 0;
        this.z.normalize();

        this.x.copy(this.Tanks[0].right);
        this.x.y = 0;
        this.x.normalize();
        
        this.heading.set(0, 0, 0);


        if(context.keyboard.isPressed(pc.input.KEY_Q)){
            

               tempC.normalize();
                
                rot = new pc.Mat4().setFromAxisAngle(pc.Vec3.UP, -16);
               // rot = new pc.Mat4().setFromEulerAngles(0, 16, 0);
               
               this.Tanks[0].forward = rot.transformVector(this.Tanks[0].forward);
               
              // console.log(TempD);
               
               //console.log(this.Tanks[0].heading);
                
               //this.heading.normalize();
               
               console.log("You just pressed Q to turn left");
                console.log(this.Tanks[0]);
                console.log(this.heading);
                
               input = true;
                    
      }

"

The values I am getting from this are;

Position: 0, 0.16059273481369019, 0
Rotation: 0, 1, 0
Euler angles: 0, 0, 0
Local rotation: NaN, NaN, NaN
Local position: NaN, NaN, NaN
Local scale: 1, 1, 1
Local Euler angles: 0, 0, 0

As you can probably guess by looking at this, the local transform is:

NaN, NaN, NaN, 0
NaN, NaN, NaN, 0
NaN, NaN, NaN, 0
NaN, NaN, NaN, 1

I have tried changing the rotation around the up axis to be 90. This does give a valid transform matrix, but when this happens I cannot move the player whatsoever. I am probably doing something daft or missing something here but this has me stumped.

On a side note, looking at the matrix here, I am guessing this is using column notation not row notation. I am used to row notation so this may effect what order I am using the vectors, although I doubt this may be the cause of this :S

Without looking too closely at the code the usual reason you end up with NaN is because of a divide by zero. This can often be caused by calling normalize() on a vector with is (0,0,0).

So first thing to check is that when you normalise a vector it isn’t zero.

I had a problem with rotating something with a rigidbody. I was not able to find a direct answer for it so that is why I post it here. I disabled the rigidbody, rotate the entity, then enabled the rigidbody again. This was the easiest way to solve it for me.