[SOLVED] Issues with diagonal camera-based movement

Hello,

After being able to make a working virtual joystick, I have now ran into another problem. I have a cube that moves acoordingly to where you move the knob around, and I want it to be related to the camera’s current view which, to some extent, does work except for diagonal movements.

When it comes to diagonal movements, to keep it diagonal you have to constantly nudge the joystick left and right, walking into an S. When I was looking around for camera-based movement, I found the first person example from PlayCanvas and went with it’s camera logic.

Movement code:

var Movement = pc.createScript('movement');
var forceX = 0;
var forceZ = 0;
//TODO: Define multipliers based on how far the knob is pulled.
var multiplierX = 0;
var multiplierZ = 0;
var moving = false;
var ground = true;
var groundDis = 0;
Movement.attributes.add('speed', {
    type: 'number',
    title: 'speed',
});
Movement.attributes.add('jumpPower', {
    type: 'number',
    title: 'Jump Power',
});
Movement.attributes.add('camera', {
    type: 'entity',
    title: 'camera',
    description: 'camera component to get the forward of'
});
Movement.attributes.add('jumpButton',{
   type: 'entity',
   title: 'Jump Button'  
});
// initialize code called once per entity
Movement.prototype.initialize = function() {   
    self = this.entity;    
    this.force = new pc.Vec3();   
    console.log(self);  
    if (this.jumpButton)
    {    
        this.jumpButton.element.on('click', function(){         
          self.script.movement.jump();         
        });     
    }   
   else console.warn("no jumping button defined"); 
};
Movement.prototype.jump = function()
{
  console.log("jump!");       
  this.entity.rigidbody.applyImpulse(0, this.jumpPower, 0);                
};
Movement.prototype.update = function(dt){
  if (this.moving)
  {
    this.entity.script.movement.move(this.forceX, this.forceZ);          
  }   
};
Movement.prototype.SetMovingTo = function(boole){   
  if (boole)
  {
    this.moving = true;       
  }  
  else this.moving = false;    
};
Movement.prototype.move = function(x, z){
    var force = this.force;
    var forward = this.camera.forward;
    var right = this.camera.right;  
    var localX = 0;
    var localZ = 0;    
    if (x > 0)
    {   
      localX += right.x;
      localZ += right.z;  
    }
    if (x < 0)
    {
      localX -= right.x;
      localZ -= right.z;  
    }
    if (z > 0)
    {
      localX += forward.x;
      localZ += forward.z;  
    }
    if (z < 0)
    {
      localX -= forward.x;
      localZ -= forward.z;  
    }
    force.set(localX, 0, localZ).normalize().scale(this.speed);
    this.entity.rigidbody.applyForce(force);
    var vel = this.entity.rigidbody.linearVelocity;
    vel = new pc.Vec3(pc.math.clamp(vel.x, -5, 5), vel.y, pc.math.clamp(vel.z, -5, 5));
    this.entity.rigidbody.linearVelocity = vel;
};
Movement.prototype.FullStop = function(){
    var linearVelocity = this.entity.rigidbody.linearVelocity;
    linearVelocity.set(0, linearVelocity.y, 0);
    this.entity.rigidbody.linearVelocity = linearVelocity;    
};

Link to the project: https://playcanvas.com/editor/project/764285

1 Like

Hi @Abneto,

Good thinking following the first person movement example. Here is though a simpler way of binding the joystick movement to the camera direction:

Movement.prototype.move = function(x, z){
    
    var force = this.force.copy(this.camera.forward).scale(this.speed * z);
    var rightForce = new pc.Vec3().copy(this.camera.right).scale(this.speed * x);
    
    force.add(rightForce);    
    force.y = 0;
    
    this.entity.rigidbody.applyForce(force);
};
3 Likes