threejs中用PLC实现鼠标控制的第三(一)人称的公式。

89 阅读1分钟

camera.position.set(

character.position.x + Math.sin(camera.rotation.y) * Math.cos(camera.rotation.x) * α

,

character.position.y + h_c - Math.sin(camera.rotation.x) * α

,

character.position.z + Math.cos(camera.rotation.y) * Math.cos(camera.rotation.x) * α

);

其中,h_c 代表角色的视角高度,也可以理解为相机轨道的球心,α 是一个距离常量,表示相机轨道的半径,当α=0时,该式为第一人称

camera.position.set(camera.position.set(

character.position.x+Math.sin(camera.rotation.y)Math.cos(camera.rotation.x)αcharacter.position.x + Math.sin({camera.rotation.y}) * Math.cos({camera.rotation.x}) * α

,

character.position.y+hcMath.sin(camera.rotation.x)αcharacter.position.y + h_c - Math.sin({camera.rotation.x}) * α

,

character.position.z+Math.cos(camera.rotation.y)Math.cos(camera.rotation.x)αcharacter.position.z + Math.cos({camera.rotation.y}) * Math.cos({camera.rotation.x}) * α

);

let controls;
let mode = "first";
// 初始化 PLC
controls = new PointerLockControls(camera, document.body);
scene.add(controls.getObject());
                
/**
 * Debug
 */
const gui = new dat.GUI({ width: 300 });
const 参数 = { 球心: 1.44, 半径: 3 };
const PLCfolder = gui.addFolder("第三人称");
PLCfolder.add(参数, "球心", 0, 5, 0.01).name("球心");
PLCfolder.add(参数, "半径", 0, 10, 0.01).name("半径");

document.addEventListener("keydown", (e) => {
	keys[e.code] = true;
	if (e.code === "ControlLeft") {
		// 切换相机模式
		if (mode === "first") {
			mode = "third";
		} else {
			mode = "first";
		}
	e.preventDefault();
});
        
          // 第一人称
		if (mode === "first") {
			character.rotation.y = camera.rotation.y; // 人物的旋转跟随相机的旋转
			camera.position.set(
				character.position.x,
				character.position.y + 1.44,
				character.position.z
			);
			camera.rotation.reorder("YXZ");
		}

		// 第三人称
		if (mode === "third") {
			character.rotation.y = camera.rotation.y;
			let Y = camera.rotation.y;
			let X = camera.rotation.x;
			let α = 参数.半径;
			camera.position.set(
				// 根据相机的旋转角度来计算相机的位置
				character.position.x + Math.sin(Y) * Math.cos(X) * α,
				character.position.y + 参数.球心 - Math.sin(X) * α,
				character.position.z + Math.cos(Y) * Math.cos(X) * α
			);
		}