相机控制
大多数应用都需要让用户移动相机。可以直接使用引擎附带的 CameraControls 脚本,位于 scripts/esm/camera-controls.mjs。单个脚本即可提供适用于生产环境的导航:
- 环绕:鼠标左键拖动绕焦点旋转,中键拖动平移,滚轮缩放。
- 飞行:WASD 键自由移动相机,右键拖动环顾四周。
- 触摸和手柄:开箱即支持多点触控手势和手柄输入。
将脚本附加到相机实体:
- 引擎
- 编辑器
- React
- Web Components
// Load the script (here from the CDN; you can also bundle it with your app)
const asset = new Asset('camera-controls', 'script', {
url: 'https://cdn.jsdelivr.net/npm/playcanvas/scripts/esm/camera-controls.mjs'
});
app.assets.add(asset);
app.assets.load(asset);
asset.ready(() => {
// Attach it to the camera entity
camera.addComponent('script');
camera.script.create('cameraControls', {
properties: {
focusPoint: new Vec3(0, 1, 0)
}
});
});
如果使用打包工具构建应用,也可以直接导入脚本类:
import { CameraControls } from 'playcanvas/scripts/esm/camera-controls.mjs';
camera.addComponent('script');
camera.script.create(CameraControls);
将 camera-controls.mjs 作为脚本资源添加到项目中(从引擎仓库复制)。然后选中相机实体,添加脚本组件,并将 cameraControls 脚本加入其中。随后可在检查器中调整脚本属性。
import { CameraControls } from 'playcanvas/scripts/esm/camera-controls.mjs';
import { Script } from '@playcanvas/react/components';
<Entity name="camera" position={[0, 1, 4]}>
<Camera />
<Script script={CameraControls} />
</Entity>
<pc-app>
<pc-asset src="https://cdn.jsdelivr.net/npm/playcanvas/scripts/esm/camera-controls.mjs"></pc-asset>
<pc-scene>
<pc-entity name="camera" position="0 1 4">
<pc-camera></pc-camera>
<pc-script>
<pc-script-instance name="cameraControls"></pc-script-instance>
</pc-script>
</pc-entity>
</pc-scene>
</pc-app>
配置
脚本提供了丰富的属性,最常用的如下:
| 属性 | 默认值 | 说明 |
|---|---|---|
enableOrbit | true | 启用环绕控制 |
enableFly | true | 启用飞行控制 |
enablePan | true | 启用平移 |
focusPoint | [0, 0, 0] | 相机环绕的焦点 |
rotateSpeed | 0.2 | 旋转灵敏度 |
moveSpeed | 10 | 飞行移动速度,另有 moveFastSpeed 和 moveSlowSpeed 变体 |
zoomSpeed | 0.001 | 缩放灵敏度 |
pitchRange | [-360, 360] | 相机俯仰角限制,单位为度 |
zoomRange | [0.01, 0] | 最小/最大缩放距离,最大值为 0 表示不限制 |
leftButton | orbit | 鼠标左键动作,参见鼠标按键 |
middleButton | pan | 鼠标中键动作 |
rightButton | look | 鼠标右键动作 |
groundPan | false | 沿地面而非视图平面平移,参见像拖动地图一样拖动地面 |
阻尼属性(rotateDamping、moveDamping、zoomDamping、focusDamping,默认均为 0.98)控制运动停止时的平滑程度,0 表示立即停止。创建纯环绕相机时禁用飞行;创建纯飞行相机时禁用环绕。
鼠标按键
leftButton、middleButton 和 rightButton 属性决定各鼠标按键的动作:
| 动作 | 说明 |
|---|---|
orbit | 绕焦点旋转视图,按住 Shift 时改为平移。 |
pan | 平移视图。 |
look | 原地转动视角,与使用按键飞行时相同。禁用 enableFly 时改为环绕。 |
none | 忽略该按键,留给应用使用。 |
默认左键环绕、中键平移、右键转动视角。在编辑器中,这些属性是检查器中的下拉选项。例如,用左键转动视角、右键环绕:
camera.script.create(CameraControls, {
properties: {
leftButton: 'look',
rightButton: 'orbit'
}
});
拖动始终遵循发起拖动的按键。拖动过程中再按第二个按键不会改变动作,因为浏览器不会将其报告为新的按下事件。
为应用保留按键
设为 none 的按键会被完全忽略,包括按下及随后的拖动,因此应用可将其用于绘画、选择等操作。其他按键和滚轮仍用于导航:
camera.script.create(CameraControls, {
properties: {
rightButton: 'none'
}
});
app.mouse.on(EVENT_MOUSEDOWN, (event) => {
if (event.button === MOUSEBUTTON_RIGHT) {
// start painting
}
});
绘画示例采用了这种方式。
像拖动地图一样拖动地面
默认平移沿视图平面移动相机。启用 groundPan 后,拖动会让地面上的点保持在光标下,就像拖动地图一样,同时保持相机高度。地面是位于 focusPoint 高度的水平面,因此应将焦点置于地面高度。双指平移也会沿地面移动。要用左键拖动地图、其他按键环绕:
camera.script.create(CameraControls, {
properties: {
leftButton: 'pan',
middleButton: 'orbit',
rightButton: 'orbit',
groundPan: true,
focusPoint: new Vec3(0, 0, 0)
}
});
示例
在引擎示例中体验该脚本:
若要编写自定义相机逻辑,环绕相机教程介绍了完整实现。