Skip to content

角色在场景中移动时被物体遮挡视野

实现思路:

用 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;
        }
      });
    }
  }
}

Released under the MIT License.