Skip to content

Latest commit

 

History

History
662 lines (554 loc) · 31.9 KB

File metadata and controls

662 lines (554 loc) · 31.9 KB

中文 | English

cesium-player-controller

注意: streaming-terrain 用于 Cesium 地球地形,不用于 3D Tiles。由于 CesiumJS 无法通过 CPU 直接获取 3D Tiles 的顶点坐标,3D Tiles 场景仍可使用 collider-forge 制作 glTF / GLB 碰撞体。

NPM Package Github X Three.js

基于 CesiumJS 的玩家控制器,开箱即用,提供人物胶囊体碰撞、Cesium 地形流式碰撞、动画、车辆驾驶、第一 / 第三人称切换和相机避障。

示例

在线示例

安装

npm install cesium-player-controller @dimforge/rapier3d-compat

本地运行

git clone https://github.com/hh-hang/cesium-player-controller.git
npm install
npm run dev

浏览器访问 http://localhost:5173/cesium-player-controller/。

使用

import {
    Cartesian3,
    Cesium3DTileset,
    Viewer,
    Math as CMath,
    Cartographic,
} from "cesium";
import "cesium/Build/Cesium/Widgets/widgets.css";
import { playerController } from "cesium-player-controller";

// 搭建 CesiumJS 环境
const viewer = new Viewer("cesiumContainer", {
    timeline: false,
    animation: false,
});

// 加载 3D Tiles 场景
const tileset = await Cesium3DTileset.fromUrl("./tileset.json");
viewer.scene.primitives.add(tileset);
await viewer.flyTo(tileset);

// 设置人物出生点
const center = tileset.boundingSphere.center;
const carto = Cartographic.fromCartesian(center);
const initPos = Cartesian3.fromDegrees(
    CMath.toDegrees(carto.longitude),
    CMath.toDegrees(carto.latitude),
    carto.height + 20,
);

// playerController 核心用法
const player = new playerController();

// 人物控制初始化
await player.init({
    viewer,   // Cesium Viewer 实例
    initPos,  // 人物初始坐标,ECEF
    playerModelConfig: {
        url: "./glb/person.glb",   // 模型路径(GLB/GLTF)
        scale: 0.01,               // 模型缩放
        idleAnim: "idle",          // 静止动画名
        walkAnim: "walk",          // 行走动画名
        runAnim: "run",            // 跑步动画名
        jumpAnim: "jump",          // 跳跃动画名;或传 ["起跳", "循环", "落地"] 分三段播放
    },
    // 静态碰撞源
    staticCollider: {
        type: "gltf",
        url: "./glb/agi-hq.glb",
        position: center,
    },
});

// 车辆控制初始化(可选)
await player.loadVehicleModel({
    url: "./glb/sedan.glb",                                        // 车辆模型 URL
    position: Cartesian3.clone(initPos),                           // 车辆位置(ECEF)
    wheelsNames: ["Wheel_LF", "Wheel_RF", "Wheel_LR", "Wheel_RR"], // 顺序:左前、右前、左后、右后
    driverSeatPosition: new Cartesian3(-0.11, 0.19, 0.84),         // 驾驶位,局部坐标
});

// 每帧调用
viewer.scene.preUpdate.addEventListener(() => {
    player.update();
});

完整参数示例

init()

await player.init({
    // 必填
    viewer,   // Cesium Viewer 实例
    initPos,  // 初始出生点(ECEF)
    playerModelConfig: {
        url: "./glb/person.glb",   // 模型路径(GLB/GLTF)
        scale: 0.01,               // 模型缩放
        idleAnim: "idle",          // 静止动画名
        walkAnim: "walk",          // 行走动画名
        runAnim: "run",            // 跑步动画名
        jumpAnim: "jump",          // 跳跃动画名;或传 ["start", "loop", "land"] 分三段播放

        // 方向动画(可选,不填则复用对应默认动画)
        leftWalkAnim: "leftWalk",         // 默认复用 walkAnim
        rightWalkAnim: "rightWalk",       // 默认复用 walkAnim
        backwardAnim: "walkBack",         // 默认复用 walkAnim
        flyAnim: "fly",                   // 默认复用 idleAnim
        flyIdleAnim: "flyIdle",           // 默认复用 idleAnim
        flyHoverForwardAnim: "flyFwd",    // 默认复用 flyAnim
        flyHoverBackAnim: "flyBack",      // 默认复用 flyIdleAnim
        flyHoverLeftAnim: "flyLeft",      // 默认复用 flyIdleAnim
        flyHoverRightAnim: "flyRight",    // 默认复用 flyIdleAnim
        flyHoverUpAnim: "flyUp",          // 默认复用 flyIdleAnim
        flyHoverDownAnim: "flyDown",      // 默认复用 flyIdleAnim
        drivingAnim: "driving",           // 驾驶动画,不填则复用 idleAnim

        // 物理参数(可选)
        gravity: -2400,     // 重力基准值,会按 scale 缩放
        jumpHeight: 600,    // 跳跃高度基准值,会按 scale 缩放
        speed: 300,         // 移动速度基准值,会按 scale 缩放
        flySpeed: 2100,     // 飞行速度基准值,会按 scale 缩放
        acceleration: 30,   // XZ 加速响应速度
        deceleration: 30,   // XZ 减速响应速度

        // 模型参数(可选)
        rotateY: 0,                            // 人物初始朝向(弧度)
        facingOffset: 0,                       // 模型正面轴校正(弧度)
        firstPersonCameraOffset: [0, 0, 0],    // 第一人称相机局部偏移(x=右、y=前、z=上,随朝向转动)
        capsuleRadiusRatio: 1,                 // 胶囊体半径倍率
    },

    // 静态碰撞源
    staticCollider: [
        // Cesium 地形流式碰撞(大范围移动时推荐)
        {
            type: "streaming-terrain",
            level: 16,
            radius: 350,
            releaseRadius: 525,
            lookAheadSeconds: 1,
            fallbackDelayMs: 250,
            maxConcurrentRequests: 2,
            maxBuildsPerFrame: 1,
            maxActiveTiles: 48,
            maxCachedMeshes: 64,
            rebaseDistance: 10_000,
        },
        // 模型碰撞
        {
            type: "gltf",
            url: `${import.meta.env.BASE_URL}glb/agi-hq.glb`,
            position: newCenter,
        },
    ],
    // 运动学碰撞源
    kinematicCollider: {
        type: "gltf",
        url: "./glb/platform.glb",
        position: initPos,
        rotation: { heading: 0, pitch: 0, roll: 0 },
        scale: 1,
    },

    // 相机(可选)
    minCamDistance: 100,           // 第三人称最小镜头距离
    maxCamDistance: 440,           // 第三人称最大镜头距离
    camLookAtHeightRatio: 0.8,     // 相机看向点高度比例,0=底部 1=顶部
    thirdMouseMode: 1,             // 鼠标控制模式 0-5,详见字段说明
    enableZoom: false,             // 是否允许滚轮缩放
    enableOverShoulderView: false, // 是否启用过肩视角
    isFirstPerson: false,          // 初始是否进入第一人称
    enableSpringCamera: false,     // 是否启用弹簧相机
    springCameraTime: 0.05,        // 弹簧相机平滑时间(秒),越小跟随越紧

    // 其他(可选)
    mouseSensitivity: 5,           // 鼠标灵敏度
    timeScale: 1,                  // 时间缩放系数,< 1 慢动作,> 1 快进
    keyMap: {                      // 自定义键位(以下为默认值;可改键、数组多绑或传 null 禁用)
        forward: ["KeyW", "ArrowUp"],        // 前进
        backward: ["KeyS", "ArrowDown"],     // 后退
        left: ["KeyA", "ArrowLeft"],         // 左移
        right: ["KeyD", "ArrowRight"],       // 右移
        sprint: ["ShiftLeft", "ShiftRight"], // 人物冲刺;车辆转向时为后轮手刹
        jump: ["Space"],                     // 人物跳跃;车辆模式下制动
        toggleView: ["KeyV"],                // 切换视角
        toggleFly: ["KeyF"],                 // 切换飞行模式
        toggleVehicle: ["KeyE"],             // 上 / 下车
    },
    isShowMobileControls: true,    // 移动端是否显示虚拟控制 UI
    mobileControls: {              // 移动端按钮显隐与样式(默认全部显示)
        joystick: true,             // 是否显示摇杆,默认 true
        jump: {                     // true 显示;对象可自定义布局和图片
            icon: "/jump.svg",
            // brakeIcon: "/brake.svg",
            right: 24,
            bottom: 32,
            size: 64,
        },
        fly: true,                  // 是否显示飞行按钮,默认 true
        view: true,                 // 是否显示视角按钮,默认 true
        vehicle: true,
    },
});

流式地形碰撞

streaming-terrain 复用 Cesium 已加载的真实地形 mesh,并在玩家或当前车辆周围动态创建、卸载 Rapier 碰撞体。它会按速度预加载前方瓦片,在 Cesium 未及时提供 mesh 时发起限流的兜底请求,并在长距离移动后重锚 Rapier 局部坐标系以保持精度。

staticCollider: {
    type: "streaming-terrain",
    // 所有字段均可选;下表列出默认值
}
  • 仅可放在 staticCollider 中,且每个控制器只支持一个 streaming-terrain 源。
  • 无需配置固定 rectangle;如果只在小范围活动,仍可使用 type: "terrain" 和 rectangle 一次性采样高度地形。
  • level 越高瓦片越精细,但请求、内存和碰撞网格成本也会增加;建议根据地形数据的实际精度调整。

loadVehicleModel()

await player.loadVehicleModel({
    // 必填
    url: "./glb/sedan.glb",                                        // 车辆模型 URL
    position: Cartesian3.clone(initPos),                           // 车辆位置(ECEF)
    wheelsNames: ["Wheel_LF", "Wheel_RF", "Wheel_LR", "Wheel_RR"], // 顺序:左前、右前、左后、右后
    driverSeatPosition: new Cartesian3(-0.11, 0.19, 0.84),         // 驾驶位,局部坐标

    // 可选
    scale: 0.9,                                // 车辆模型缩放,默认 1
    driverSeatRotation: 0,                     // 驾驶位相对底盘局部坐标的水平旋转(弧度),默认 0
    chassisRatio: 0.2,                         // 底盘高度比例,默认 0.2
    suspensionRestLengthRatio: 0.2,            // 悬挂静止长度比例,默认 0.2
    followVehicleDirection: true,              // 驾驶时镜头跟随车辆朝向,默认 true
    mass: 1500,                                // 车辆质量基准值(kg),会按 scale 缩放,默认 1500
    maxSpeed: 300,                             // 最高速度基准值(km/h),会按 scale 缩放,默认 300
    acceleration: 8,                           // 加速度基准值(m/s²),会按 scale 缩放,默认 8
    deceleration: 8,                           // 制动减速度基准值(m/s²),会按 scale 缩放,默认 8
});

车辆模式下,W / S 控制前进和倒车,A / D 转向,Space 制动,转向时按住 Shift 可使用后轮手刹。翻车后不会自动复位;resetVehicle() 未内置默认键,可按需绑定:

window.addEventListener("keydown", (event) => {
    if (event.code === "KeyR" && !event.repeat) player.resetVehicle();
});

API

生命周期

方法 说明
init(opts, callback?) 初始化控制器,资源加载完成后执行 callback。
update(delta) 每帧更新移动、碰撞、相机和动画。
destroy() 销毁控制器并移除事件监听。
reset(pos?) 将角色重置到指定位置或初始位置。
switchPlayerModel(model) 运行时切换角色模型,并保留当前位置和朝向。
loadVehicleModel(opts) 加载车辆,可重复调用加载多辆车。
resetVehicle() 将当前驾驶车辆翻正复位(未上车时无效)。
changeView() 切换第一 / 第三人称视角。
setFirstPersonCamera(vertAngle?) 直接进入第一人称,可指定初始垂直角度。
setFirstPersonCameraOffset(offset) 运行时设置第一人称相机局部偏移,顺序为 [右, 前, 上]。
addKinematicCollider(collider, source?) 注册运动学碰撞体。
removeKinematicCollider(source) 移除已注册的运动学碰撞体。
clearKinematicColliders() 移除所有运动学碰撞体。

动态物体

可被角色推动、受重力与碰撞模拟的物体(球 / 方块 / 圆柱 / 圆锥)。

import { Cartesian3, Color, EllipsoidGeometry, GeometryInstance, Primitive,
    PerInstanceColorAppearance, ColorGeometryInstanceAttribute, VertexFormat } from "cesium";

// 1) 创建动态物体(物理:半径 0.25 的球)
const ball = player.addDynamicObject(spawnEcef, { kind: "ball", radius: 0.25 }, { density: 30, restitution: 0.3 });

// 2) 自行创建视觉并加入场景(这里用内置几何,也可换成 Model.fromGltfAsync 加载 glb)
const sphere = new Primitive({
    geometryInstances: new GeometryInstance({
        geometry: new EllipsoidGeometry({ radii: new Cartesian3(0.25, 0.25, 0.25), vertexFormat: VertexFormat.POSITION_AND_NORMAL }),
        attributes: { color: ColorGeometryInstanceAttribute.fromColor(Color.ORANGE) },
    }),
    appearance: new PerInstanceColorAppearance(),
    asynchronous: false,
});
viewer.scene.primitives.add(sphere);

// 3) 绑定视觉,库每帧自动同步位姿
ball.attachVisual(sphere);

// 移除时:库只移物理,视觉需自行从场景移除
player.removeDynamicObject(ball);
viewer.scene.primitives.remove(sphere);
方法 说明
addDynamicObject(positionEcef, shape, opts?) 创建动态物体,返回句柄 DynamicObject。shape 见 DynamicShape,opts 见 DynamicBodyOpts。
removeDynamicObject(obj) 移除一个动态物体(仅移物理与 debug 线框;视觉需自行从场景移除)。
clearDynamicObjects() 移除所有动态物体(同上,视觉需自行清理)。

DynamicObject 句柄方法:

方法 说明
attachVisual(visual) 绑定一个带 modelMatrix 的视觉对象,库每帧自动同步其位姿。
detachVisual() 解绑视觉(不销毁视觉,仅停止同步)。

状态获取

方法 返回内容
getPosition() 当前角色位置,类型为 Cartesian3。
getVelocity() 当前角色速度,返回 { e, n, u }。
getIsFirstPerson() 当前是否为第一人称。
getIsFlying() 当前是否处于飞行模式。
getIsOnGround() 当前是否在地面上。
getControllerMode() 控制模式,0 为人物,1 为车辆。
getPlayerModel() 当前加载的人物模型对象。
getPlayerCapsule() 角色胶囊体尺寸信息。
getActiveVehicle() 当前正在使用的车辆实例。
getAllVehicles() 所有已加载车辆实例。
getCollider() Rapier 角色碰撞体。
getCurrentPlayerAnimationName() 当前播放的动画片段名,没有则返回 null。
getCenterScreenRaycastHit() 屏幕中心射线检测结果,适合做瞄准或交互。
getActiveKinematicCollider() 当前玩家站立的运动学碰撞体,不在运动学碰撞体上时返回 null。
getCurrentLocomotionSet() 当前移动动作组名。

输入与运行时控制

方法 说明
setInput(input) 注入外部输入状态,适合手柄或自定义按键系统。
setKeyMap(map?) 运行时自定义键位;不传则恢复默认键位(见自定义键位)。
setMouseSensitivity(v) 设置鼠标灵敏度。
setPlayerScale(v) 动态修改角色缩放,并同步碰撞相关参数。
setPlayerSpeed(v) 设置移动速度。
setPlayerFlySpeed(v) 设置飞行速度。
setJumpHeight(v) 设置跳跃高度。
setGravity(v) 设置重力。
setMinCamDistance(v) 设置第三人称最小镜头距离。
setMaxCamDistance(v) 设置第三人称最大镜头距离。
setCamLookAtHeightRatio(v) 设置第三人称相机看向点高度比例(0=底部,1=顶部)。
setThirdMouseMode(v) 设置第三人称鼠标模式:`0
setEnableZoom(v) 设置是否允许镜头缩放。
setOverShoulderView(v) 开关过肩视角偏移。
setDebug(v) 开关碰撞体调试显示;流式地形模式下会同步显示已加载瓦片和 ENU 局部坐标轴(E 红 / N 绿 / U 蓝)。
setEnableToward(v) 开关鼠标驱动的朝向 / 视角更新。

输入监听

init() 完成后键盘和鼠标监听已默认开启,无需手动调用。以下两个方法用于运行时临时关闭再恢复监听。

player.offAllEvent(); // 关闭键盘和鼠标输入监听
player.onAllEvent();  // 重新开启键盘和鼠标输入监听

默认键位

动作 默认键 功能
forward W / ArrowUp 前进
backward S / ArrowDown 后退
left A / ArrowLeft 左移
right D / ArrowRight 右移
sprint Shift 人物冲刺;车辆转向时使用后轮手刹
jump Space 人物跳跃;车辆制动
toggleView V 切换视角
toggleFly F 切换飞行模式
toggleVehicle E 上车 / 下车
- 鼠标移动 / 拖拽 控制视角

自定义键位

通过 keyMap 可以把上表的任意动作改绑到其它按键,或禁用某个动作。键名使用 KeyboardEvent.code(如 "KeyE"、"ArrowUp"、"Space",注意是 "KeyE" 而非 "e")。

每个动作三种取值:

  • 不填 -> 使用默认键
  • 字符串 / 字符串数组 -> 替换为指定按键(数组可绑定多个键)
  • null -> 禁用该动作(任何键都不会触发)

初始化时配置:

await player.init({
    // ...
    keyMap: {
        forward: "KeyE",          // 改为按 E 前进(替换默认 W / ↑)
        jump: null,               // 禁用跳跃
        left: ["KeyA", "KeyJ"],   // 同时绑定 A 和 J
        // 其余动作未填,保持默认键
    },
});

运行时切换键位方案:

player.setKeyMap({ forward: "KeyI", backward: "KeyK" }); // 应用新键位
player.setKeyMap();                                      // 恢复全部默认

setInput

player.setInput({
    moveX: number,         // 水平移动轴,范围 -1~1
    moveY: number,         // 纵向移动轴,范围 -1~1
    lookDeltaX: number,   // 视角水平增量,通常来自 mousemove 的 movementX
    lookDeltaY: number,   // 视角垂直增量,通常来自 mousemove 的 movementY
    jump: boolean,        // 跳跃,持续状态;飞行时控制上升,车辆模式下制动
    shift: boolean,       // 冲刺/加速,持续状态;车辆转向时为后轮手刹
    toggleView: boolean,  // 触发式,传 true 切换第一/第三人称视角
    toggleFly: boolean,   // 触发式,传 true 切换飞行模式
    toggleVehicle: boolean, // 触发式,传 true 上车 / 下车
});

动画

方法 说明
playPlayerAnimationByName(name) 按动画片段名直接播放角色动画。
registerAnimation(key, clipName, opts?) 注册自定义动画片段。
playAnimation(key, opts?) 播放已注册的自定义动画。
registerLocomotionSet(setName, map) 注册一套移动动画集合,用于替换内置移动动画。
switchLocomotionSet(setName) 切换到指定的移动动画集合。

registerAnimation

player.registerAnimation(key, clipName, {
    loop?: boolean,              // 是否循环播放,默认 true
    timeScale?: number,          // 动画播放缩放,默认 1
    duration?: number,           // 动画播放时长,默认 0
    clampWhenFinished?: boolean, // 是否在播放结束后保持末帧,默认 false
    onFinished?: () => void,     // 动画播放结束后触发
});

playAnimation

player.playAnimation(key, {
    force?: boolean,        // 为 true 时强制从头重播,即使当前已在播放该动画
    returnToPrev?: boolean, // 仅对一次性动画生效,播放结束后自动恢复上一个动画状态
});

registerLocomotionSet

支持的 key:idle | walking | walking_backward | running | jumping | flyidle | flying,填写的 key 会替换对应内置动画,未填的保持原有动画。

player.registerLocomotionSet("combat", {
    idle: "CombatIdle",
    walking: "CombatWalk",
    walking_backward: "CombatBack",
    running: "CombatRun",
    jumping: "CombatJump",
    flyidle: "CombatFlyIdle",
    flying: "CombatFly",
});

事件

player.onAnimationChange = (name) => {};       // 角色当前动画切换时触发
player.onBeforeViewChange = (isFirstPerson) => {}; // 第一 / 第三人称切换前触发
player.onViewChange = (isFirstPerson) => {};   // 第一 / 第三人称切换后触发
player.onGroundChange = (onGround) => {};      // 落地状态变化时触发
player.onVehicleEnter = (vehicle) => {};       // 上车完成后触发
player.onVehicleExit = (vehicle) => {};        // 下车完成后触发
player.onTowardChange = (dx, dy, speed) => {}; // 朝向 / 视角输入更新时触发

字段说明

PlayerControllerOptions

字段 类型 必填 默认值 说明
viewer Viewer 是 - Cesium Viewer 实例。
playerModelConfig PlayerModelOptions 是 - 角色模型与参数配置。
initPos Cartesian3 是 - 初始出生点(ECEF)。
staticCollider ColliderSource | ColliderSource[] 否 - 静态碰撞体来源;不传则仅使用基础贴地检测。
kinematicCollider ColliderSource | ColliderSource[] 否 - 初始化时注册的运动学碰撞体;不支持 streaming-terrain。
mouseSensitivity number 否 5 鼠标灵敏度。
minCamDistance number 否 100 第三人称最小镜头距离。
maxCamDistance number 否 440 第三人称最大镜头距离。
camLookAtHeightRatio number 否 0.8 第三人称相机看向点高度比例(0=胶囊底部,1=顶部)。
thirdMouseMode 0 | 1 | 2 | 3 | 4 | 5 否 1 第三人称视角下的鼠标控制模式(0:隐藏鼠标,控制朝向及视角;1:隐藏鼠标,仅控制视角;2:显示鼠标,拖拽控制朝向及视角;3:显示鼠标,拖拽仅控制视角;4:显示鼠标,拖拽控制视角且人物朝向跟随相机水平方向;5:隐藏鼠标,控制视角且人物朝向跟随相机水平方向)。
enableZoom boolean 否 false 是否允许滚轮缩放。
enableOverShoulderView boolean 否 false 是否启用过肩视角。
isFirstPerson boolean 否 false 初始化时是否直接进入第一人称。
enableSpringCamera boolean 否 false 是否启用弹簧相机。
springCameraTime number 否 0.05 弹簧平滑时间(秒),越小跟随越紧。
timeScale number 否 1 时间缩放系数,< 1 慢动作,> 1 快进。
keyMap KeyMap 否 默认键位 自定义键位映射,详见自定义键位。
isShowMobileControls boolean 否 true 是否在移动端显示虚拟控制 UI。
mobileControls MobileControlsOptions 否 全部显示 移动端按钮显隐、位置、尺寸和图片配置。

PlayerModelOptions

字段 类型 必填 默认值 说明
url string 是 - 人物模型路径(GLB/GLTF)。
scale number 是 - 人物模型缩放。
idleAnim string 是 - Idle 动画名。
walkAnim string 是 - Walk 动画名。
runAnim string 是 - Run 动画名。
jumpAnim string | [string, string, string] 是 - 跳跃动画名。传字符串播放单一动画;传三元数组 [起跳, 循环, 落地] 分三阶段播放。
leftWalkAnim string 否 walkAnim 左移动画名,不填则复用 walkAnim。
rightWalkAnim string 否 walkAnim 右移动画名,不填则复用 walkAnim。
backwardAnim string 否 walkAnim 后退动画名,不填则复用 walkAnim。
flyAnim string 否 idleAnim 飞行动画名,不填则复用 idleAnim。
flyIdleAnim string 否 idleAnim 飞行待机动画名,不填则复用 idleAnim。
flyHoverForwardAnim string 否 flyAnim 飞行前进时的悬停动画名。
flyHoverBackAnim string 否 flyIdleAnim 飞行后退时的悬停动画名。
flyHoverLeftAnim string 否 flyIdleAnim 飞行左移时的悬停动画名。
flyHoverRightAnim string 否 flyIdleAnim 飞行右移时的悬停动画名。
flyHoverUpAnim string 否 flyIdleAnim 飞行上升时的悬停动画名。
flyHoverDownAnim string 否 flyIdleAnim 飞行下降时的悬停动画名。
drivingAnim string 否 idleAnim 驾驶动画名,不填则复用 idleAnim。
gravity number 否 -2400 重力基准值(按 scale 缩放)。
jumpHeight number 否 600 跳跃高度基准值(按 scale 缩放)。
speed number 否 300 移动速度基准值(按 scale 缩放)。
flySpeed number 否 2100 飞行速度基准值(按 scale 缩放)。
rotateY number 否 0 人物初始朝向(弧度)。
facingOffset number 否 0 模型正面轴校正(弧度)。
firstPersonCameraOffset [number, number, number] 否 [0,0,0] 第一人称相机局部偏移。基于胶囊顶部,在玩家朝向系(x=右、y=前、z=上)下叠加,随 yaw 转动,按 scale 缩放。
capsuleRadiusRatio number 否 1 胶囊体半径倍率。
acceleration number 否 30 XZ 方向加速响应速度,值越大加速越快。
deceleration number 否 30 XZ 方向减速响应速度,值越大停止越快。

ColliderSource

类型 字段 说明
terrain rectangle, resolution? Cesium 地形碰撞源,rectangle 为 [west, south, east, north] 弧度。
streaming-terrain 全部字段可选 跟随玩家或车辆动态流式加载 Cesium 真实地形 mesh;仅支持 staticCollider。
gltf url, position?, rotation?, scale?, modelMatrix? glTF / GLB 碰撞源。

StreamingTerrainCollider

字段 类型 默认值 说明
level number 16 物理地形的四叉树层级。
radius number 350 预测位置周围需加载碰撞的半径(米)。
releaseRadius number radius * 1.5 已加载瓦片的卸载半径(米),不小于 radius。
lookAheadSeconds number 1 按当前速度预加载前方地形的时间(秒)。
fallbackDelayMs number 250 等待 Cesium 自身加载后再发起兜底请求的延迟(毫秒)。
maxConcurrentRequests number 2 最大并发兜底地形请求数。
maxBuildsPerFrame number 1 每次 update() 最多创建的 Rapier trimesh 数量。
maxActiveTiles number 48 同时活跃的最大瓦片数。
maxCachedMeshes number 64 适配器缓存的已解码 Cesium TerrainMesh 上限。
rebaseDistance number 10000 触发 Rapier 局部世界重锚的水平移动距离(米,最小 100)。

VehicleOptions

字段 类型 必填 默认值 说明
url string 是 - 车辆模型路径(GLB/GLTF)。
position Cartesian3 是 - 车辆初始世界坐标(ECEF)。
wheelsNames string[] 是 - 车轮节点名数组,顺序为左前、右前、左后、右后。
scale number 否 1 车辆模型缩放。
driverSeatPosition Cartesian3 是 - 驾驶位胶囊中心,车辆底盘局部坐标。
driverSeatRotation number 否 0 驾驶位相对车辆底盘局部坐标的水平旋转(弧度)。
chassisRatio number 否 0.2 底盘高度比例。
suspensionRestLengthRatio number 否 0.2 悬挂静止长度比例。
followVehicleDirection boolean 否 true 驾驶时镜头是否跟随车辆朝向。
mass number 否 1500 车辆质量基准值(kg,按 scale 缩放)。
maxSpeed number 否 300 最高速度基准值(km/h,按 scale 缩放)。
acceleration number 否 8 加速度基准值(m/s²,按 scale 缩放)。
deceleration number 否 8 制动减速度基准值(m/s²,按 scale 缩放)。

DynamicShape

动态物体的碰撞形状,几何参数为世界尺度(米)。

kind 字段 说明
ball radius 球。
box half 方块,half 为 ENU 三轴半边长 { e, n, u }。
cylinder halfHeight, radius 圆柱,轴沿本地 Up。
cone halfHeight, radius 圆锥,轴沿本地 Up(尖朝上)。

DynamicBodyOpts

字段 类型 必填 默认值 说明
density number 否 1 密度,影响质量与被推动手感(质量 = 体积 × 密度)。
restitution number 否 0.2 弹性,0 不反弹,1 完全弹。
friction number 否 0.6 摩擦。
linearDamping number 否 0.4 线性阻尼,越大滑行越快停。
angularDamping number 否 0.6 角阻尼,越大旋转越快停。

MobileControlsOptions

字段 类型 必填 默认值 说明
joystick boolean 否 true 是否显示摇杆。
jump boolean | JumpButtonOptions 否 true 跳跃/刹车按钮;false 隐藏,对象可自定义图片和布局。
fly boolean | MobileButtonOptions 否 true 飞行按钮;对象可配置位置、尺寸和图片。
view boolean | MobileButtonOptions 否 true 视角切换按钮;对象可配置位置、尺寸和图片。
vehicle boolean | MobileButtonOptions 否 true 上下车按钮;false 隐藏,对象可自定义图片和布局。

MobileButtonOptions / JumpButtonOptions

字段 类型 必填 默认值 说明
left / right number 否 内置位置 按钮距离左侧或右侧的位置(px)。设置 left 且未设置 right 时会清除默认右侧定位。
top / bottom number 否 内置位置 按钮距离顶部或底部的位置(px)。设置 top 且未设置 bottom 时会清除默认底部定位。
size number 否 56 圆形按钮直径(px)。
icon string 否 英文标签 自定义图片 URL。
brakeIcon string 否 BRAKE 标签 仅用于 JumpButtonOptions,设置车辆模式下的刹车图片 URL。

移动端摇杆输出 -1~1 连续方向轴,支持 360° 移动。

反馈

如果你有任何问题或者好的想法欢迎提交 issue

致谢

CesiumJS

Rapier