首页 > 其他分享 >three.js实现相机碰撞,相机不穿墙壁、物体

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

时间:2024-04-25 15:55:33浏览次数:23  
标签:distance intersects three js 相机 cameraToPlayerDistance let speed

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

关键词:数字孪生、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

标签:distance,intersects,three,js,相机,cameraToPlayerDistance,let,speed
From: https://www.cnblogs.com/chaogex/p/18157888

相关文章

  • JS之调用百度地图接口进行打卡
    调用百度地图接口进行打卡1.在百度地图开放平台申请AK2.在index.html导入百度地图SDK(此AK值为假)<scripttype="text/javascript"src="https://api.map.baidu.com/api?v=2.0&ak=f029hEOpyCQnXySQsug94D1yUU0Yil"></script>3.新增coordTransform.js//定义一些常量varx_PI......
  • lazarus数据序列为JSON
    uses  DataSet.Serialize, fpjson;varobj:tjsonobject;procedureTForm1.Button1Click(Sender:TObject);beginuniquery1.Close;uniquery1.SQL.clear;uniquery1.sql.Add('selecttop2*fromtunit');uniquery1.Open;memo1.text:=uniquery1......
  • 【2024最新】获取街道、镇级的地图geoJson数据方法
    一、目的1、在echarts上绘制市级以下的区、县的区域地图。2、在市级下很多都是有区、县的区域,而少部分是不存在区、县的,是直接市下面一级就是街道、镇级别的区域。3、统一管理区域数据,有区县的市直接拿区县的geoJson数据,没有区县的市级直接拿街道、镇级的geoJson数据来绘制区......
  • js逆向实战之智通财经网token参数解密
    url:https://www.zhitongcaijing.com/immediately.html分析过程抓流量包,主要关注如下这条数据包。响应数据如下。由于该url中的token参数是经过加密的,所以目的就是找到加密过程。关键字搜索immediately/content-list.html,只有两条记录,第一处是个html代码,肯定不是,所以只......
  • 使用 NestJS 和 qrcode.js 创建 QR 码生成器 API
    前言QR码(QuickResponseCode)是一种二维码,于1994年开发。它能快速存储和识别数据,包含黑白方块图案,常用于扫描获取信息。QR码具有高容错性和快速读取的优点,广泛应用于广告、支付、物流等领域。通过扫描QR码,用户可以快速获取信息和实现便捷操作,为现代生活带来便利。在本教程中,小编......
  • js获取当前的操作系统
    在JavaScript中,没有直接的方式来获取操作系统的信息,因为出于安全考虑,浏览器不允许访问这些信息。但是,你可以通过用户代理字符串(User-Agentstring)来间接地推断操作系统信息。以下是一个简单的JavaScript函数,用于解析用户代理字符串以推断操作系统://获取操作系统类型fu......
  • Python基础-模块和包(hashlib、random、json、time、datetime和os模块)
    什么是模块和包?模块:python中的.py文件,将一些功能按照某一种维度进行划分;自定义、内置。、第三方.包:文件夹里面好多个.py文件。在讨论的时候,一般统称为:模块。学习:自定义模块和包+使用内置模块+使用第三方模块+使用1自定义模块和包1.1快速上手-项目文件夹(......
  • idea启动jsp项目
    idea启动jsp项目1、idea打开jsp项目:2、项目配置:3、项目启动~~~~~~~~~~~~~~~~~~~~~over~~~~~~~~~~~~~~~~   ......
  • js逆向实战之莫莫铺子sign参数解密
    url:http://mmpz.ttzhuijuba.com/?r=/l&cids=1&site=classify&sort=0分析过程抓取流量包。主要关注图中框起来这条流量包,因为这条流量包返回的是当前页面数据。该流量包的url地址有个加密的参数sign,目的就是找到sign参数的加密过程。按照常规思路会去搜索url中的关键......
  • vis.js时间轴数据处理
    代码案例<!doctypehtml><html><head><title>Timeline</title><scripttype="text/javascript"src="https://unpkg.com/vis-timeline@latest/standalone/umd/vis-timeline-graph2d.min.js"></script>......