Hi! I am doing a project in which a player moves around the scene using WASD. He can also jump on the space button. When a player stands still and makes a jump, everything works as it should. But when a player starts moving during a jump, he doesn’t fall. Can you please tell how you can solved the problem? I think that need to somehow add the force vector to the impulse vector, but I don’t know how to do it.
https://playcanv.as/b/GWOdN0TA/
// Create PlayerMovement script.
var PlayerMovement = pc.createScript('playerMovement');
// Add attributes to the script.
PlayerMovement.attributes.add('movementSpeed', {
type: 'number',
default: 0.025
});
PlayerMovement.attributes.add('jumpPower', {
type: 'number',
default: 200.0
});
PlayerMovement.attributes.add('raycastPlayerBase', {
type: 'entity'
});
PlayerMovement.attributes.add('cameraEntity', {
type: 'entity'
});
// initialize code called once per entity
PlayerMovement.prototype.initialize = function() {
this.eulers = new pc.Vec3();
this.force = new pc.Vec3();
this.jumping = {
state: false
};
};
// Обновление кода каждый кадр позицию игрока
PlayerMovement.prototype.update = function(dt) {
// Get application reference.
var app = this.app;
// Get players force vector.
var force = this.force;
// Get camera direction vectors.
var forward = this.cameraEntity.forward;
var right = this.cameraEntity.right;
// Movement logic. Listen for key presses and apply changes to directional vector components.
var x = 0;
var z = 0;
if (app.keyboard.isPressed(pc.KEY_W)) {
x += forward.x;
z += forward.z;
}
if (app.keyboard.isPressed(pc.KEY_A)) {
x -= right.x;
z -= right.z;
}
if (app.keyboard.isPressed(pc.KEY_S)) {
x -= forward.x;
z -= forward.z;
}
if (app.keyboard.isPressed(pc.KEY_D)) {
x += right.x;
z += right.z;
}
// Jump code, checking if the space key was pressed instead of is pressed. This is important as we don't want to call the jump code multiple times.
// We set a jump state to ensure that we can't jump whilst already jumping.
// The jump power is passed in from the script attributes. This should be a high number.
if (app.keyboard.wasPressed(pc.KEY_SPACE)) {
if (this.jumping.state === false) {
this.entity.rigidbody.applyImpulse(0, this.jumpPower, 0);
this.jumping.state = true;
}
} else if (this.jumping.state === true) {
// If the raycast finds a collision, we assume it is an obect we can land on, we therefor reset our jump state so we can jump again.
if (this._checkBelow() !== null) {
this.jumping.state = false;
}
}
// Convert x and z directional vector components to a force vector, normalise and then scale to the movement speed.
if (x !== 0 || z !== 0) {
x *= dt;
z *= dt;
force.set(x, 0, z).normalize().scale(this.movementSpeed);
this.entity.translate(force);
this.entity.rigidbody.applyForce(force);
this.entity.rigidbody.syncEntityToBody();
}
// Если была нажата клавиша R, то нужно вызвать функцию reset()
if (app.keyboard.wasPressed(pc.KEY_R)) {
this.reset();
}
};
// Обновляем позицию камеры (postUpdate) после отработки Game Loop (update) для расчета позиции игрока
// Rotate the player to face the same direction as the camera angle
PlayerMovement.prototype.postUpdate = function(dt) {
// Установка координат для дижения модели перпендикулярно Plain (в противном случае - физика не работает)
var targetY = this.cameraEntity.script.playerCameraMovement.eulers.x;
var targetAngle = new pc.Vec3(0, targetY, 0);
this.entity.setEulerAngles(targetAngle);
};
// Raycast for checking if there is an entity below with collision and rigid body components. Returns null if no collision.
// Make sure the scene has a entity to use as a raycast point at the base of your character.
PlayerMovement.prototype._checkBelow = function() {
return this.app.systems.rigidbody.raycastFirst(this.entity.getPosition(), this.raycastPlayerBase.getPosition());
};
PlayerMovement.prototype.reset = function () {
this.entity.rigidbody.teleport(0, 0.5, 0);
this.entity.rigidbody.linearVelocity = pc.Vec3.ZERO;
this.entity.rigidbody.angularVelocity = pc.Vec3.ZERO;
};