three.js實現相機碰撞,相機不穿牆壁、物體

大家好,本文實現了相機碰撞檢測,使相機不穿牆壁、物體,並給出了思路和代碼,感謝大家~

關鍵詞:數字孿生、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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章