[SOLVED] Camera script like an editor

Hi everyone,

I need a script that allows you to move the camera in the following way:

  • via mouse: by clicking with the left button and moving the mouse, orbit around the current center of the scene;
  • via mouse + shift key: move the camera in the scene up, down, right, left (pan);
  • via keyboard (WASD): move forward and backward (not zoom) and left / right (in fly mode) regardless of the current camera angle (not along the axes).

Can anyone help me? Can someone please write a script for that please?

1 Like

the orbit camera script of this scene I think you could use Orbit camera | Learn PlayCanvas

1 Like

Thank you very much for the suggestion … in truth I had started from exactly this, but I cannot integrate the fly camera functionality (using the WASD keys) … every attempt of mine to move using the keys, always made the scene in the center …

what I would need would be merging this script Orbit camera | Learn PlayCanvas (orbit) with this other one First Person Movement | Learn PlayCanvas (first person movement)

in which the basic behavior is that of the first person movement (WASD + mouse that rotates the view from the current point) + click with the left mouse button to orbit the current center of the scene, and pressing shift together with the left click to pan

does anyone know how to modify this script so that in addition to keeping its basic behavior, it can also make a fly mode work?

One idea is to add the keyboard key is pressed checks in the orbit-camera.js update method and move the camera pivot point as a response.

If you move it in the world axis you will get I think the behaviour you are looking for.

Try posting in the collaboration or jobs category if you are looking for someone to write this.

as tested in the method update if(this.app.keyboard.wasPressed(pc.KEY_W)){
this.camera.translate(new pc.vec3(0.1,0,0)
}

No I mean translating the following property:

// orbit-camera.js
this.pivotPoint

That’s the target point the orbit camera is looking to.

Here is a quick example I drafted, adding all code for coherency in the keyboard-input.js script:

// update code called every frame
KeyboardInput.prototype.update = function (dt) {
    if (this.orbitCamera) {
        if (this.app.keyboard.wasPressed(pc.KEY_SPACE)) {
            this.orbitCamera.reset(this.startYaw, this.startPitch, this.startDistance);
            this.orbitCamera.pivotPoint = this.startPivotPosition;
        }
    }

    const keyboard = this.app.keyboard;
    const forward = keyboard.isPressed(pc.KEY_W);
    const backward = keyboard.isPressed(pc.KEY_S);
    const left = keyboard.isPressed(pc.KEY_A);
    const right = keyboard.isPressed(pc.KEY_D);

    const speed = 3;

    let xOffset = 0;
    if (forward) xOffset += speed * dt;
    if (backward) xOffset -= speed * dt;

    let zOffset = 0;
    if (left) zOffset -= speed * dt;
    if (right) zOffset += speed * dt;

    this.orbitCamera.pivotPoint.x += xOffset;
    this.orbitCamera.pivotPoint.z += zOffset;
};

Of course I am not sure what you are looking to do with it exactly since moving the camera like this on the world axis can be confusing to the user.
https://playcanvas.com/editor/scene/1315766

1 Like

thanks guys…

and thanks Leonidas, this is very helpful! but what I wanted to achieve is not exactly that …

in this example, the camera moves along the Cartesian axes, and actually creates confusion! What I need is to move the camera forward / backward and left / right relative to the current view …

for example, starting the example project you linked, the axes are rotated (which is fine, it’s a real starting situation), but I would like the camera to move forward (in this case towards the cube) as if the player was walking forward (if the cube was to the left or right of the scene, that the camera was moving forward anyway and not towards the cube), therefore independently of the Cartesian axes …

just like a camera movement in first person … I don’t know if I made myself clear …

anyway thank you very much and thank you for any other help / suggestions …

Big update! I integrated the script of the first person movement in the one suggested by Leonidas and now it works as I wanted … more or less …

if I orbit the camera to the left or right and via WASD I move, everything works fine … but if I orbit up or down, tilting the y axis, W and S no longer move correctly forwards and backwards …

do you know how to add y axis handling to this script?

the modified script is as follows:

KeyboardInput.prototype.update = function (dt) {
    if (this.orbitCamera) {
        if (this.app.keyboard.wasPressed(pc.KEY_SPACE)) {
            this.orbitCamera.reset(this.startYaw, this.startPitch, this.startDistance);
            this.orbitCamera.pivotPoint = this.startPivotPosition;
        }
    }

	const camera = this.entity;
	
	const speed = 3;

    const keyboard = this.app.keyboard;
    const key_forward = keyboard.isPressed(pc.KEY_W);
    const key_backward = keyboard.isPressed(pc.KEY_S);
    const key_left = keyboard.isPressed(pc.KEY_A);
    const key_right = keyboard.isPressed(pc.KEY_D);

    const forward = camera.forward;
    const right = camera.right;

    let x = 0;
    let z = 0;

    if (key_left) { x -= right.x; z -= right.z; }
    if (key_right) { x += right.x; z += right.z; }
    if (key_forward) { x += forward.x; z += forward.z; }
    if (key_backward) { x -= forward.x; z -= forward.z; }
	
    this.orbitCamera.pivotPoint.x += x * dt * speed;
    this.orbitCamera.pivotPoint.z += z * dt * speed;	
};

Thanks again for any help or suggestions

1 Like

Hi @fiaful! Is the script applied to the camera entity itself or another entity?

Hi @Albertos! This script is applied to the camera entity… if you would try, the complete script is:

var KeyboardInput = pc.createScript('keyboardInput');

KeyboardInput.prototype.initialize = function() {
    this.orbitCamera = this.entity.script.orbitCamera;
}

// update code called every frame
KeyboardInput.prototype.update = function (dt) {
    if (this.orbitCamera) {
        if (this.app.keyboard.wasPressed(pc.KEY_SPACE)) {
            this.orbitCamera.reset(this.startYaw, this.startPitch, this.startDistance);
            this.orbitCamera.pivotPoint = this.startPivotPosition;
        }
    }

	const camera = this.entity;
	
	const speed = 3;

    const keyboard = this.app.keyboard;
    const key_forward = keyboard.isPressed(pc.KEY_W);
    const key_backward = keyboard.isPressed(pc.KEY_S);
    const key_left = keyboard.isPressed(pc.KEY_A);
    const key_right = keyboard.isPressed(pc.KEY_D);

    const forward = camera.forward;
    const right = camera.right;

    let x = 0;
    let z = 0;

    if (key_left) { x -= right.x; z -= right.z; }
    if (key_right) { x += right.x; z += right.z; }
    if (key_forward) { x += forward.x; z += forward.z; }
    if (key_backward) { x -= forward.x; z -= forward.z; }
	
    this.orbitCamera.pivotPoint.x += x * dt * speed;
    this.orbitCamera.pivotPoint.z += z * dt * speed;	
};

What do you expect and what is the actual result?

Can you share a link of your project so we can also see the setup and result?

here you can find a sample project : PlayCanvas 3D HTML5 Game Engine

the WASD keys work correctly as long as the orbit is done only to the left and to the right …

but if you tilt up or down and then try to go forward with the W key or back with the S key, the shift does not take into account the y axis …

what I would need, more than a first person movement, would be a starship movement …

Thanks for your interest!

I see the problem. If no one else knows a solution for this I can see if I can solve this problem when I have more time.

No idea what this is. :see_no_evil:

well … starship movement is my personal interpretation … I thought it was intuitive but obviously it is not! :slight_smile:

in the first person movement, the person moves backward and forward (as well as being able to turn left and right), but standing on the ground and unable to fly, therefore the movement is a Cartesian XY …

but if we go into space with a starship, this in addition to being able to move in a Cartesian XY way, can raise and lower the bow, and therefore point its forward movement also upwards or downwards … as well as the phase take-off or landing of an airplane, when the airplane moves away from or approaches the runway …

I hope I have been able to explain it …

thanks again … I keep looking for how to do it myself, but any help is much appreciated … and I will definitely update the post promptly if I manage to do it myself (although at the moment I have serious doubts) :slight_smile:

1 Like

ok… I’m an idiot… :slight_smile: I tried dozens of different ways and the solution was trivial, right in front of my eyes…

just add the y component of the forward vector to the pivot:

const forward = camera.forward;
const right = camera.right;

let x = 0;
let z = 0;
let y = 0;

if (key_left) { x -= right.x; z -= right.z; }
if (key_right) { x += right.x; z += right.z; }
if (key_forward) { x += forward.x; z += forward.z; y += forward.y; }
if (key_backward) { x -= forward.x; z -= forward.z; y -= forward.y; }

this.orbitCamera.pivotPoint.x += x * dt * speed;
this.orbitCamera.pivotPoint.z += z * dt * speed;    
this.orbitCamera.pivotPoint.y += y * dt * speed;

we can close this topic… I thank all those who wasted time with me :slight_smile:

I leave the project to all those who can be of help here: PlayCanvas 3D HTML5 Game Engine

happy coding!

2 Likes

(how can I edit the topic title to add [SOLVED] in the head? I couldn’t find it …)

1 Like

Did that for you! Normally you should be seeing an edit icon to the right of the title:

image

1 Like

I was expecting exactly such a thing … but it wasn’t there! I’ll try to pay more attention to the next topic … (because I’m afraid I’ll open many more :laughing: )

1 Like

I think editing the title for regular members may work only up to a certain number of hours since post creation.

@yaustar @albertos do you know anything on this?

1 Like