ThirdPersonControls

Hello,

i’m trying to create a third person view, found in many online games such as Fortnite, PUBG, etc.

I’ve found the PointerLockControls which is a start, however instead of moving the camera, I have to move the object in front of the camera and make the camera follow this object such that the BACK is always shown. That is, rotating the camera should rotate around the Y axis of the object, moving forward/backward/sideways is as in the implementation of PointerLockControls.

I tried the following, where “objectt” is a new 3DObject instance, I pass that to

this.controls = new PointerLockControls(this.objectt, this.renderer.domElement);

then I got this code to update the position of the goblin according to the movements of PointerLockControls

var goblin = this.scene.getObjectByName('goblin')

console.log(goblin)

// foward
vec.setFromMatrixColumn( this.objectt.matrix, 0 );
vec.crossVectors(this.objectt.up, vec );
goblin.position.addScaledVector( vec, moveForwardSteps );
//console.log(goblin)

// right
console.log(moveRightSteps)
vec.setFromMatrixColumn( this.objectt.matrix, 0 );
goblin.position.addScaledVector( vec, moveRightSteps );

//goblin.quaternion.setFromEuler( this.objectt.rotation );

this.camera.position.y = goblin.position.y + HEIGHT * 2;

this.camera.lookAt(goblin.position);

This “works” as the camera points vertically down on the goblin I can move every direction, but I can’t rotate around the goblin which seems to be the core problem.

I don’t understand how to shift the camera a bit so you get a titled view AND rotated it around the character correctly. It strange that there is no such thing as a ThirdPersonControls? I would like to contribute that if you can help me figure this out.

3 Likes

@kolarius

Fortunately, currently, I needed to create a model like the one you were looking for … check out the following code:

https://jsfiddle.net/Fyrestar/6519yedL/

I’ll leave the code here, creator: Fyrestar

var camera, scene, renderer, mesh, goal;

var time = 0;
var newPosition = new THREE.Vector3();
var matrix = new THREE.Matrix4();

var stop = 1;
var DEGTORAD = 0.01745327;
var temp = new THREE.Vector3;

init();
animate();

function init() {

    camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 10 );
    camera.position.set( 0, 2, - 2 );
    
    scene = new THREE.Scene();
    camera.lookAt( scene.position );

    var geometry = new THREE.BoxBufferGeometry( 0.2, 0.2, 0.2 );
    var material = new THREE.MeshNormalMaterial();

    mesh = new THREE.Mesh( geometry, material );
    
    goal = new THREE.Object3D;
    
    mesh.add( goal );
    scene.add( mesh );
    
    goal.position.set(0, 2, -2);
    
    var gridHelper = new THREE.GridHelper( 4, 10 );
    scene.add( gridHelper );
    
    scene.add( new THREE.AxesHelper() );

    renderer = new THREE.WebGLRenderer( { antialias: true } );
    renderer.setSize( window.innerWidth, window.innerHeight );
    document.body.appendChild( renderer.domElement );

}

function animate() {

    requestAnimationFrame( animate );
    
    time += 0.01;


	if ( time > stop ) {
    	
      mesh.rotateY( Math.random() * 360 * DEGTORAD);
      
      stop = time + Math.random() * 1;
    
    }
	mesh.translateZ(0.01);
    
    temp.setFromMatrixPosition(goal.matrixWorld);
    
    camera.position.lerp(temp, 0.2);
    camera.lookAt( mesh.position );
    
    renderer.render( scene, camera );

}

He helped me set up my camera with the interaction of the third person. From the moment you study the code, you know what each line does, you can adapt it to your goal. Consult the documentation of the Three Js!

Hi @Rozz,

thanks for this example code, I came across this already, but this is not exactly what i’m looking for.
and yes, i tried adapting it but I failed since up and down is camera-based, while rotating should be around the object as in the example. I can’t get them both to work

I only added this to the code, the rest remains the same (i removed the movement on Z axis)

var tempLock = new THREE.Object3D();
 controls = new PointerLockControls(tempLock, renderer.domElement);

and then in the update loop, because i think I should just use the rotation around the Y component for the mesh, but this doesn’t seem to work decent. i guess this is not the correct calculation but i’m clueless

function animate() {

    requestAnimationFrame( animate );
   

    mesh.rotateY(tempLock.rotation.y * 0.01)
    //mesh.rotateX(tempLock.rotation.x * 0.01)
    //mesh.translateZ(0.01);
    
    temp.setFromMatrixPosition(goal.matrixWorld);
    
    camera.position.lerp(temp, 1);
    camera.lookAt( mesh.position );
    
    
    
    renderer.render( scene, camera );

I need to have movement like third person in real games where rotating your mouse rotates around the object etc. It needs to be together with the pointerlockcontrols.

You can use trigonometry and vector operations to make pointerlockcontrols third-person.

import { PointerLockControls } from “three/examples/jsm/controls/PointerLockControls.js”;
let controls;
controls = new PointerLockControls(camera, document.body);
scene.add(controls.getObject());

// 第三人称(Third Person)
character.rotation.y = camera.rotation.y;
// 限制相机的旋转角度(Limiting the camera’s rotation angle)
camera.rotation.x = Math.max(
-Math.PI / 4,
Math.min(Math.PI / 5, camera.rotation.x)
);
// 根据相机的旋转角度来计算相机的位置(Calculate the camera position based on the camera’s rotation angle)
camera.position.set(
character.position.x +
Math.sin(camera.rotation.y) * Math.cos(camera.rotation.x) * 3,
character.position.y + 1.44 + -Math.sin(camera.rotation.x) * 3,
character.position.z +
Math.cos(camera.rotation.y) * Math.cos(camera.rotation.x) * 3
);