# Camera 摄像机组件
相机是用户获取图像的视角,游戏中的一帧图像是由若干个相机的渲染结果组成。
# 在方案工具中创建Camera组件
在属性检查器中点击新增->others->Camera即可创建Camera组件:
# 使用代码创建Camera组件
示例:
// 创建Entity
const mainCameraEntity = engine.game.createEntity3D("MainCamera");
// 设置相机Entity位置
mainCameraEntity.transform.position = engine.Vector3.createFromNumber(0, 0 , -10);
// 添加Camera组件
const mainCameraComp = mainCameraEntity.addComponent(engine.Camera);
// 设置为透视相机
mainCameraComp.projectionType = engine.Camera.ProjectionType.Perspective;
// 添加到世界
engine.game.sceneRoot.transform.addChild(mainCameraEntity.transform);
# 在方案工具中查看相机视锥体预览
在层级管理器点击具有Camera组件的Entity,即可在场景编辑器视角中看到相机产生的视锥体线框:
# 视口宽高比自适应
Camera的Aspect属性决定了视口的宽高比,如图所示:
如果宽高比与渲染目标的宽高比不匹配,则会出现画面被拉伸的情况,如图所示:
自适应aspect,aspect = 1.77,画面比例正常
指定aspect,aspect = 1.0,画面明显被拉伸
想要开启Aspect自适应,只需在Camera的属性面板中,将aspectType设置为Auto。
# 使用多相机渲染
场景的一帧允许由多个相机渲染而成,顺序由场景中的所有相机的depth
从小到大渲染。
示例:
// 设置主相机深度值为0
mainCameraComp.depth = 0;
// 主相机绘制前需要清屏
mainCameraComp.clearFlag = 1;
// 设置clearColor
mainCameraComp.clearColor = new engine.Color(255,255,255,0);
// 创建第二个相机的Entity
const secondCameraEntity = engine.Entity.createEntity3D("MainCamera");
secondCameraEntity.transform.position = engine.Vector3.createFromNumber(0, 0 , 100);
// 添加Camera组件
const secondCameraComp = secondCameraEntity.addComponent(engine.Camera);
// 设置为正交相机
secondCameraComp.projectionType = engine.Camera.ProjectionType.Orthographic;
// 设置深度值为1,在主相机之后渲染
secondCameraComp.depth = 1;
// 绘制前不需要清屏
secondCameraComp.clearFlag = 0;
// 添加到世界
game.world.add(secondCameraComp);
# 渲染到贴图
Camera可以将图像渲染到主屏,也可以渲染到一张贴图上,从而实现例如镜面、装备面板展示等效果。
示例:
// 创建 200x400 大小的渲染贴图
const rtWidth = 200;
const rtHeight = 400;
const rt = new engine.RenderTexture(rtWidth, rtHeight);
secondCameraComp.targetTexture = rt;
# 射线检测 & 对象拾取
有时候需要在点击屏幕时拾取对象,拾取对象通常有两种实现方式:
- 像素拾取
- 包围球拾取
其中像素拾取的方式精度较高,在移动平台上开销非常高,通常不建议使用 目前支持包围球拾取的方式,使用方法如下:
declare let cameraComp;
declare let visibleList: engine.Entity;
const rayCaster = new engine.Raycaster();
// touchX,touchY为归一化的屏幕坐标
rayCaster.setFromCamera([touchX, touchY], cameraComp.entity);
const intersections = rayCaster.intersectEntities();