Hi i have a teleport camera and when my player enter a dungeon he got teleport-ed, but the orbit function stop working. Any idea why? I have tried different things to reactivate it after the teleport but nothing worked.
Hi @ayrin !
I have some theories, but can you please share an editor link so I can take a look?
https://playcanvas.com/editor/project/674858
sure, i forgot sorry @Codeknight999
To recreate the error you have to enter the dungeon in the ruins north/of the village slightly east, there is a downstair
Solved the orbit camera issue,
Can you please share how you fixed it?
here is all my code, is very messy coz there are many try out that are not useful anymore, but i have locked the mouse jmovement ust when the right button is clicked
var NewCamera = pc.createScript('newCamera');
// Configurable attributes
NewCamera.attributes.add("elevation", {type:"number", default:-40});
NewCamera.attributes.add("distance", {type:"number", default:8});
NewCamera.attributes.add("farDistance", {type:"number", default:10});
NewCamera.attributes.add("closeDistance", {type:"number", default:1});
NewCamera.attributes.add("rotationSpeed", {type:"number", default:0.2});
NewCamera.attributes.add("zoomSpeed", {type:"number", default:2});
// initialize code called once per entity
NewCamera.prototype.initialize = function() {
this.target = this.app.root.findByName("Player");
this.model = this.app.root.findByName('Top').script.playerStat.pmodel;
this.type = 0; // 0 = external, 1 = first-person
// Internal orbit state
this.orbitYaw = 0;
this.orbitElevation = 20;
this.orbitPitch = this.elevation;
this.distance = 10;
// Mouse input
this.rightMouseDown = false;
// Usa document per catturare tutti i mousemove
document.addEventListener('mousemove', this.onMouseMove.bind(this));
document.addEventListener('mousedown', (event) => {
if(event.button === 2){ // destro
this.rightMouseDown = true;
// richiedi pointer lock
document.body.requestPointerLock();
}
});
document.addEventListener('mouseup', (event) => {
if(event.button === 2){
this.rightMouseDown = false;
// esci dal pointer lock
document.exitPointerLock();
}
});
// Wheel per zoom
this.app.mouse.on(pc.EVENT_MOUSEWHEEL, this.onMouseWheel, this);
};
NewCamera.prototype.restoreOrbit = function () {
if (!this.target || !this.entity.camera) return;
// Forza modalità orbit
this.type = 0;
// Ripristina tutti i layer (fondamentale per la testa)
var layers = this.app.scene.layers.layerList;
this.entity.camera.layers = layers.map(function (l) {
return l.id;
});
// Ripristina orbita, ma solo se non definita
if (typeof this.orbitYaw === "undefined") {
var forward = this.target.forward.clone();
// evita forward zero
if (forward.lengthSq() > 0.001) {
this.orbitYaw = Math.atan2(forward.x, forward.z) * pc.math.RAD_TO_DEG;
} else {
this.orbitYaw = 0; // fallback
}
}
if (typeof this.orbitElevation === "undefined") {
this.orbitElevation = pc.math.clamp(this.orbitElevation || 20, -80, 80);
}
// Mantieni la distanza attuale ma clamp tra valori min/max
this.distance = pc.math.clamp(
this.distance || this.distance,
this.closeDistance,
this.farDistance
);
// Aggiorna subito la posizione senza resettare lo yaw
this.updateExternal(0);
};
NewCamera.prototype.onMouseMove = function(event) {
if(this.type === 0 && this.rightMouseDown) {
// Usa event.movementX/Y che funziona con pointer lock
var dx = event.movementX || event.mozMovementX || event.webkitMovementX || 0;
var dy = event.movementY || event.mozMovementY || event.webkitMovementY || 0;
this.orbitYaw -= dx * this.rotationSpeed;
this.orbitElevation = pc.math.clamp(this.orbitElevation - dy * this.rotationSpeed, -80, 80);
}
};
NewCamera.prototype.onMouseWheel = function(event) {
if(this.type === 0) {
this.distance -= event.wheel * 0.05 * this.zoomSpeed;
this.distance = pc.math.clamp(this.distance, this.closeDistance, this.farDistance);
}
};
// Called every frame, after update
NewCamera.prototype.postUpdate = function(dt) {
if(!this.target) return;
if(this.type === 0) {
this.updateExternal(dt);
} else if(this.type === 1) {
this.firstperson(dt);
}
// Switch camera type
if(this.app.keyboard.wasPressed(pc.KEY_V)) {
this.type = 1 - this.type; // toggle between 0 and 1
}
};
// External orbit camera
NewCamera.prototype.updateExternal = function(dt) {
if (!this.target) return;
var targetPos = this.target.getPosition();
var verticalOffset = 0.5; // altezza sopra il player
// Converti yaw e elevation in radianti
var radYaw = this.orbitYaw * pc.math.DEG_TO_RAD;
var radElevation = this.orbitElevation * pc.math.DEG_TO_RAD;
// Coordinate sferiche
var x = this.distance * Math.cos(radElevation) * Math.sin(radYaw);
var y = this.distance * Math.sin(radElevation);
var z = this.distance * Math.cos(radElevation) * Math.cos(radYaw);
// Posizione camera
var camX = targetPos.x + x;
var camY = targetPos.y + y + verticalOffset;
var camZ = targetPos.z + z;
// Clamp verticale soft: evita che la camera vada sotto player, ma non blocca orbita
var minY = targetPos.y + 0.1; // leggermente sopra player
if (camY < minY) camY = minY;
this.entity.setPosition(camX, camY, camZ);
// Guarda sempre il player
var lookAtPos = targetPos.clone().add(new pc.Vec3(0, verticalOffset, 0));
this.entity.lookAt(lookAtPos);
};
// Keep your existing first-person camera method
NewCamera.prototype.firstperson = function(dt) {
this.entity.setPosition(this.target.getPosition());
this.entity.translateLocal(0,0.3,0);
this.entity.setRotation(this.target.getRotation());
if(this.tilt === 1) {
var a = this.entity.getLocalEulerAngles().x;
if(a === 0){
this.entity.rotateLocal(a - 45, 0, 0);
} else {
this.entity.rotateLocal(a - 225, 0, 0);
}
this.entity.translateLocal(1,0,0);
}
};