Skip to content

简介

在场景中可同时拥有无限数量的摄像机。这些摄像机可设置为以任何顺序在屏幕上任何位置或仅在屏幕的某些部分进行渲染。

摄像机切换

默认情况下,摄像机会用它所渲染的画面覆盖整个屏幕,因此同一时刻只能在屏幕中看到一个摄像机的画面,即 深度(Depth)属性值最大的摄像机。通过在脚本中禁用一个摄像机并启用另一个,即可从一个摄像机的镜头切换到另一个,从而得到场景的多个镜头画面。在某些情况下,例如要在俯瞰地图视角和第一人称视角之间切换时,就可以采用这种方法。

【Multiple_Cameras001.mp4】

视频中所演示的就是通过启用和禁用摄像机进行视角切换的效果。

渲染画中画

通常情况下,您希望至少有一个摄像机视图覆盖整个屏幕(默认设置),但在屏幕的一个小区域内显示另一个摄像机的视图往往也很常见。例如,您可能会在第一人视角的屏幕角落里俯瞰显示小地图。您可以在 检视窗口(Inspector)中通过设置 摄像机(Camera)组件(Component)的 视口(View Port)属性,来设置摄像机渲染的视图在屏幕上显示的位置和尺寸。

【Multiple_Cameras002.mp4】

视频中所演示的就是通过设置摄像机组件的 视口(View Port)属性制作小地图的效果。

值得注意的是,小视图的摄像机的 深度(Depth)属性值需要设置为一个高于背景摄像机的值,因为 深度(Depth)属性值更高的摄像机的渲染画面会覆盖在较低值摄像机的渲染画面之上。

【Multiple_Cameras003.png】

用于渲染小视图的摄像机的 深度(Depth)属性值会高于渲染第三人称视角画面的摄像机的 深度(Depth)属性值。

摄像机渲染

除了常规地将摄像机捕获的内容直接渲染到屏幕,您也可以将摄像机捕获的内容渲染到纹理中,这对于制作在 3D 场景中显示根据游戏逻辑实时变化的动态 2D 画面会非常有帮助,例如制作镜子和传送门。您可以在脚本中创建 RenderTexture 类型的变量,并将其通过 API Camera.targetTexture 设置为摄像机捕获的纹理输出位置,然后摄像机捕获的内容将通过 RenderTexture 类型的变量将捕获的内容渲染到纹理中。

【Multiple_Cameras004.mp4】

视频中所演示的就是将摄像机捕获的内容渲染至场景中 3D 对象 平面(Plane)的纹理上的效果。

将摄像机捕获的纹理渲染至场景中使用默认材质的 平面(Plane)游戏对象(Game Object)的代码示例如下:

typescript
class CamRender extends Component {
    //定义公共变量获取摄像机的 Camera 组件
    public TheCamera:Camera;
    //定义公共变量获取渲染摄像机捕获的内容的 PlaneA 游戏对象
    public PlaneA:GameObject;

    //定义私有变量保存可以渲染到的纹理
    private _renderTexture:RenderTexture;

    /*
    辑运行时事件;
    */
    OnStart(): void {
        //获取 PlaneA 的本地缩放,这样渲染的内容就会跟随 PlaneA 的尺寸显示,防止画面变形
        let planeALocalScale:Vector3 = this.PlaneA.transform.localScale;
        //定义渲染纹理
        this._renderTexture = RenderTexture.CreateRenderTexture(
            planeALocalScale.x * 1024, 
            planeALocalScale.y * 1024, 
            RenderTextureFormat.RGBA32, 
            DepthType.Depth24Stencil8
        );
        //设置摄像机的目标纹理为渲染纹理,这样摄像机捕获的内容就会渲染到渲染纹理上
        this.TheCamera.targetTexture = this._renderTexture;
        //获取 PlaneA 的网格渲染器和对应的材质
        let planeAMeshRenderer:MeshRenderer = this.PlaneA.GetComponent(MeshRenderer);
        let planeAMat:Material = planeAMeshRenderer.material;
        //由于 PlaneA 上使用的是预设材质,可以直接通过 "_MainTex" 属性来设置渲染纹理为摄像机捕获的内容
        planeAMat.SetTexture("_MainTex", this._renderTexture);
    }

    OnUpdate(): void {
    }

}

其中关于渲染纹理的设置方法和关于预设材质所使用的 着色器(Shader)具体属性名称,可参阅 着色器 和 材质 章节。

值得注意的是,如果摄像机捕获的内容与实际渲染的内容发生了镜像差异,您可以将该游戏对象发生镜像变化方向的 缩放(Scale)改为负数解决该问题。

【Multiple_Cameras005.gif】