角色在场景中移动时被物体遮挡视野
实现思路:
用 raycaster 检测像机与角色之间的物体ins
,如果它们的距离小于像机与角色的距离,则说明场景内物体处于像机和角色之间,此时会遮挡玩家的视野(看不到角色了),那么将这些ins
的 material 材质透明度调低。具体参见seePlayer
方法。
js
class Game {
tmpVec3 = new THREE.Vector3();
tmpCameraVec3 = new THREE.Vector3();
betweenObjects = [];
constructor() {
// 视野穿透判断
this.camera.getWorldPosition(this.tmpCameraVec3);
this.seePlayer(this.tmpCameraVec3, true);
}
/**
* !!!优化场景中的物体遮挡玩家的问题
* 判断物体是否在摄像机和角色位置之间,是的话「让之间的物体透明」
* !!! 用到了 distanceTo 方法
* @param {*} pos 相机位置
*/
seePlayer(pos) {
// 还原被透明化的物体
if (this.betweenObjects.length) {
this.betweenObjects.map((item) => {
item.material.transparent = false;
item.material.opacity = 1;
});
this.betweenObjects = [];
}
this.tmpVec3.copy(this.root.position).sub(pos).normalize(); //方向
let ray = new THREE.Raycaster(pos, this.tmpVec3);
let ins = ray.intersectObjects(this.scene.children, true);
if (ins.length) {
// 实时计算「像机与玩家的距离」
let distanceBetweenPlayerAndCamera = this.root.position.distanceTo(pos);
ins.map((item) => {
if (
item.distance < distanceBetweenPlayerAndCamera - 0.2 &&
item.object.name != "地面"
) {
this.betweenObjects.push(item.object);
item.object.material.transparent = true;
item.object.material.opacity = 0.3;
}
});
}
}
}