three.js实现相机碰撞,相机不穿墙壁、物体

three,js · 浏览次数 : 0

小编点评

**代码摘要:** 该代码实现了一个相机碰撞检测功能,使相机不穿墙壁、物体。当相机和人物之间有物体时,会平滑拉进或恢复默认距离,否则会跟随人物移动。 **关键思路:** 1. 从人物往相机发送射线,与场景进行相交检测。 2. 如果最近相交点小于默认距离,说明相机被遮挡,将相机沿着相机到人物的方向平滑移动。 3. 如果在拉进时,人物往相机反方向移动,则可以移动到默认的距离而保持相机不动;再远相机就会跟随了实现后效果。 **实现步骤:** 1. 导入三个库:`Raycaster`、`Scene`、`Vector3`。 2. 定义一个名为 `handleCameraCollision`的函数,接受 `raycaster`、`scene`、`defaultDistance`、`playerWorldPosition`和 `cameraCurrentWorldPosition`参数。 3. 从人物往相机方向创建一个 `playerToCameraDirection`向量。 4. 使用 `raycaster.intersectObject`方法检测最近相交点。 5. 计算相机到人物距离的默认值 `cameraToPlayerDistance`。 6. 比较相机到人物距离和默认距离,如果最近相交点小于默认距离并且最近相交点的距离大于默认距离,则表示相机被遮挡,将相机平滑移动到人物方向上。 7. 如果最近相交点大于或等于默认距离,则表示相机没有被遮挡,将相机恢复到默认距离。 8. 计算相交点到人物距离的比例作为移动的速度。 9. 如果最近相交点不在默认距离范围内,则将移动的速度设置为 0。 10. 如果最近相交点在默认距离范围内,则将移动的速度设置为物体到人物距离的比例。 11. 如果最近相交点不在场景中,则返回一个指向空向量的向量。 12. 最后,将 `playerToCameraDirection`方向和移动的速度添加到相机位置上。

正文

大家好,本文实现了相机碰撞检测,使相机不穿墙壁、物体,并给出了思路和代码,感谢大家~

关键词:数字孪生、three.js、Web3D、WebGL、相机碰撞、游戏相机

我正在承接Web3D数字孪生项目,具体介绍可看承接各种Web3D业务

实现前:
image

移动第三人称相机时,相机可能会穿入到物体、墙壁中,影响视野

现在进行下面的改进:

  • 只要相机和人物之间有物体,就平滑拉进
  • 如果没有物体,则恢复默认的距离
  • 如果在拉进时,人物往相机反方向移动,则可以移动到默认的距离而保持相机不动;再远相机就会跟随了

实现后效果如下:
image

实现原理

大概的实现原理如下:

从人物往相机发送射线,与场景进行相交检测;
如果最近相交点小于默认距离,则说明相机被遮挡,将相机沿着相机到人物的方向平滑移动

代码:

import { Raycaster, Scene, Vector3 } from "three"

type cameraVelocity = Vector3

export let handleCameraCollision = (raycaster: Raycaster, scene: Scene, defaultDistance: number, playerWorldPosition: Vector3, cameraCurrentWorldPosition: Vector3): cameraVelocity => {
    let playerToCameraDirection = cameraCurrentWorldPosition.clone().sub(playerWorldPosition).normalize()

    raycaster.set(playerWorldPosition, playerToCameraDirection)


    let intersects = raycaster.intersectObject(scene, true)

    let cameraToPlayerDistance = cameraCurrentWorldPosition.clone().distanceTo(playerWorldPosition)

    //实现“如果没有物体,则恢复默认的距离”和“如果在拉进时,人物往相机反方向移动,则可以移动到默认的距离而保持相机不动;再远相机就会跟随了”
    if (cameraToPlayerDistance < defaultDistance
        && (
            intersects.length == 0
            || intersects[0].distance > cameraToPlayerDistance
        )
    ) {
        let speed
        if (intersects.length == 0 || intersects[0].distance > defaultDistance) {
            speed = defaultDistance / cameraToPlayerDistance
        }
        else {
            speed = intersects[0].distance / cameraToPlayerDistance

            if (intersects[0].distance + speed > cameraToPlayerDistance) {
                speed = 0
            }
        }


        return playerToCameraDirection.clone().multiplyScalar(speed)
    }

    if (intersects.length == 0 || intersects[0].distance >= cameraToPlayerDistance) {
        return new Vector3(0, 0, 0)
    }

    let cameraToPlayerDirection = playerWorldPosition.clone().sub(cameraCurrentWorldPosition).normalize()
    let speed = cameraToPlayerDistance / intersects[0].distance

    return cameraToPlayerDirection.multiplyScalar(speed)
}


...

camera.position.add(handleCameraCollision(...))

参考资料

【C#】【Unity】第三人称摄像机跟随人物移动时碰撞到墙壁等,摄像机不穿越墙壁

[UE4]第三人称探索类游戏的镜头控制思路与经验分享

第三人称视角游戏的镜头全自动控制方案

Raycaster Collision Detection

与three.js实现相机碰撞,相机不穿墙壁、物体相似的内容:

three.js实现相机碰撞,相机不穿墙壁、物体

大家好,本文实现了相机碰撞检测,使相机不穿墙壁、物体,并给出了思路和代码,感谢大家~ 关键词:数字孪生、three.js、Web3D、WebGL、相机碰撞、游戏相机 我正在承接Web3D数字孪生项目,具体介绍可看承接各种Web3D业务 目录实现原理参考资料 实现前: 移动第三人称相机时,相机可能会穿

Three.js中实现一个OBBHelper

本文参考Box3Helper源码,并写出一个OBBHelper

Three.js实现可透视的水面效果

本文描述使用Three.js实现可透视的水面效果

Three.js中实现碰撞检测

本文就如何在Three.js中进行碰撞检测进行记述

如何使用webgl(three.js)实现煤矿隧道、井下人员定位、掘进面、纵采面可视化解决方案——第十九课(一)

three.js、webgl、3D煤矿隧道、三维井下人员定位、掘进面三维可视化、纵采面可视化、采集面可视化展示、设备检测、数字孪生、物联网3D、3d建筑、3d库房,bim管理系统

Three.js中实现对InstanceMesh的碰撞检测

1. 概述 之前的文章提到,在Three.js中使用InstanceMesh来实现性能优化,可以实现单个Mesh的拾取功能 那,能不能实现碰撞检测呢?肯定是可以的,不过Three.js中并没有直接的API可以实现对InstanceMesh的碰撞检测,需要手动实现 回顾本文的描述的Three.js的场

Three.js使用InstancedMesh实现性能优化

本文记述在three.js中使用InstancedMesh来实现绘制大量几何体的性能优化

three.js高性能渲染室外场景

大家好,本文在相关文章的基础上,使用three.js渲染了高性能的室外场景,在移动端也有较好的性能,并给出了代码,分析了关键点,感谢大家~ 关键词:three.js、Web3D、WebGL、室外场景、Instanced Draw、大场景、LOD、Frustum Cull、优化、开源 代码:Githu

基于 Three.js 的 3D 模型加载优化

作为一个3D的项目,从用户打开页面到最终模型的渲染加载的时间也会比普通的H5项目要更长一些,从而造成大量的用户流失。为了提升首屏加载的转化率,需要尽可能的降低loading的时间。这里就分享一些我们在模型加载优化方面的心得。

第135篇:Three.js基础入门

好家伙,这东西太帅了,我要学会 先放张帅图(都是用three.js做出来的,这我学习动力直接拉满) 还有另外一个 Junni is... 帧数太高,录不了 开始学习 官方文档 1.Three.js是什么? Three.js是一款运行在浏览器中的 3D 引擎(基于WebGL的API的封装),你可以用它