https://playcanvas.com/editor/scene/2254172
I created a 3D box so that my other 3 friends can access and use it as an avatar when launching into playcanvas. I disable the camera and enable this object plus its camera.
I added the script below which is called playController.js
var PlayerController = pc.createScript('playerController');
PlayerController.attributes.add('moveSpeed', {
type: 'number',
default: 5,
title: 'Move Speed'
});
PlayerController.attributes.add('lookSpeed', {
type: 'number',
default: 0.2,
title: 'Look Speed'
});
PlayerController.attributes.add('jumpForce', {
type: 'number',
default: 500,
title: 'Jump Force'
});
// This attribute will hold the reference to your Camera entity
PlayerController.attributes.add('cameraEntity', {
type: 'entity',
title: 'Camera Entity'
});
// initialize code called once per entity
PlayerController.prototype.initialize = function() {
this.app.mouse.on(pc.EVENT_MOUSEDOWN, this.onMouseDown, this);
this.app.mouse.on(pc.EVENT_MOUSEUP, this.onMouseUp, this); // Keep for potential future use
this.app.mouse.on(pc.EVENT_MOUSEMOVE, this.onMouseMove, this);
this.app.keyboard.on(pc.EVENT_KEYDOWN, this.onKeyDown, this);
this.eulers = new pc.Vec2();
// Initialize eulers from the entity's current rotation if available
var currentEuler = this.entity.getRotation().getEulerAngles();
this.eulers.x = currentEuler.y; // Yaw
this.eulers.y = this.cameraEntity ? this.cameraEntity.getRotation().getEulerAngles().x : 0; // Pitch
if (!this.cameraEntity) {
console.error("PlayerController: Camera entity not assigned to script attribute.");
}
// Lock the mouse pointer
this.app.mouse.emulateContextMenu = false; // Prevent right-click context menu
this.app.mouse.disableContextMenu(); // Ensures context menu is off even if pointer lock fails or is exited
};
// FIX: Corrected onMouseDown function
PlayerController.prototype.onMouseDown = function (event) {
// Enable pointer lock when any mouse button is pressed down (clicked)
this.app.mouse.enablePointerLock();
};
PlayerController.prototype.onMouseUp = function (event) {
// You might want to disable pointer lock here or handle other mouse interactions
// For now, it's just a placeholder, as pointer lock typically persists until Esc or Tab change
};
PlayerController.prototype.onMouseMove = function (event) {
if (pc.Mouse.isPointerLocked()) {
this.eulers.x -= event.dx * this.lookSpeed;
this.eulers.y -= event.dy * this.lookSpeed;
// Clamp camera pitch (up/down rotation)
this.eulers.y = pc.math.clamp(this.eulers.y, -90, 90);
// Apply rotation to the player entity for yaw (left/right)
// Only rotate around the Y-axis (up axis)
this.entity.setEulerAngles(0, this.eulers.x, 0);
// Apply rotation to the camera entity for pitch (up/down)
// Make sure the camera's local rotation is relative to the player
if (this.cameraEntity) {
this.cameraEntity.setLocalEulerAngles(this.eulers.y, 0, 0);
}
}
};
PlayerController.prototype.onKeyDown = function (event) {
if (event.key === pc.KEY_SPACE && this.entity.rigidbody) {
// Apply a vertical impulse for jumping if the entity has a rigid body
// You might want to add a check here to only jump if grounded
this.entity.rigidbody.applyImpulse(0, this.jumpForce, 0);
}
};
// update code called every frame
PlayerController.prototype.update = function(dt) {
if (!this.entity.rigidbody) {
// Warn if the rigid body is missing, as movement relies on it
console.warn("PlayerController: No Rigid Body component found on entity. Movement will not work.");
return;
}
var forward = new pc.Vec3();
var right = new pc.Vec3();
var force = new pc.Vec3();
// Get player's forward and right vectors based on its current rotation
forward.copy(this.entity.forward).scale(this.moveSpeed);
right.copy(this.entity.right).scale(this.moveSpeed);
// Accumulate movement forces based on keyboard input
if (this.app.keyboard.isPressed(pc.KEY_W)) {
force.add(forward);
}
if (this.app.keyboard.isPressed(pc.KEY_S)) {
force.sub(forward);
}
if (this.app.keyboard.isPressed(pc.KEY_A)) {
force.sub(right);
}
if (this.app.keyboard.isPressed(pc.KEY_D)) {
force.add(right);
}
// Apply force to the rigid body (horizontal movement only, maintain current Y velocity)
// Note: applyForce adds force continuously, applyImpulse applies it once.
this.entity.rigidbody.applyForce(force.x, 0, force.z);
// Optional: Limit maximum horizontal velocity to prevent infinite acceleration
var linearVel = this.entity.rigidbody.linearVelocity;
var horizontalVel = new pc.Vec3(linearVel.x, 0, linearVel.z);
var maxHorizontalSpeed = this.moveSpeed * 1.5; // Allow a bit more than base moveSpeed
if (horizontalVel.length() > maxHorizontalSpeed) {
horizontalVel.normalize().scale(maxHorizontalSpeed);
this.entity.rigidbody.linearVelocity = new pc.Vec3(horizontalVel.x, linearVel.y, horizontalVel.z);
}
};
When I launch it, I would see the object, and then object would fall like .1 second due to gravity into the water, but then the W A S D and the camera (arrows) would not work at all.
I clicked also with the mouse to try to make them work but they dont work.
Any recommendations to set this up?