项目中往往同时存在主场景摄像机、UI 摄像机、角色预览摄像机和 RenderTexture 摄像机。如果各系统直接操作 Unity Camera,主摄像机切换、URP Camera Stack、AudioListener 和跟随逻辑就会散落到不同代码中。
MyFramework 使用 CameraManager 统一管理摄像机,并通过 GameCamera 为 Unity Camera 增加组件化能力。
项目地址:
一、框架默认摄像机
CameraManager.init() 会创建:
bash
MainCamera 默认主摄像机
UICamera UGUI 摄像机
BlurCamera UI 背景模糊摄像机
常用接口:
bash
GameCamera mainCamera =
mCameraManager.getMainCamera();
GameCamera uiCamera =
mCameraManager.getUICamera();
GameCamera blurCamera =
mCameraManager.getUIBlurCamera();
业务代码应通过 GameCamera 操作摄像机,而不是反复查找 Unity Camera。
二、创建并切换主摄像机
场景中存在 BattleCamera 节点时,可以直接创建包装对象:
bash
public class BattleCameraSystem : FrameSystem
{
protected GameCamera mBattleCamera;
public override void init()
{
base.init();
mBattleCamera =
mCameraManager.createCamera(
"BattleCamera");
mCameraManager.setMainCamera(
mBattleCamera);
}
public override void destroy()
{
mCameraManager
.resetToDefaultMainCamera();
mCameraManager.destroyCamera(
mBattleCamera);
mBattleCamera = null;
base.destroy();
}
}
setMainCamera() 会停用旧主摄像机,再激活新摄像机。销毁当前主摄像机后,框架会尝试恢复默认摄像机,避免没有可用主摄像机。
三、GameCamera 提供的能力
GameCamera 继承自 MovableObject,除了位置和旋转,还封装了:
bash
FOV 与正交尺寸
渲染层和 Camera Depth
屏幕坐标转世界坐标
RenderTexture
URP Camera Stack
后处理开关
目标跟随组件
例如屏幕坐标转换:
bash
Vector3 worldPos =
mCameraManager.getMainCamera()
.screenToWorld(screenPos, false);
设置正交大小:
bash
mBattleCamera.setOrthoSize(540.0f);
设置可见层:
bash
mBattleCamera.setVisibleLayer(layerMask);
四、让摄像机跟随角色
GameCamera 内置了多种连接器:
bash
CameraLinkerThirdPerson
CameraLinkerSmoothFollow
CameraLinkerFirstPerson
CameraLinkerFree
CameraLinkerSmoothRotate
例如平滑跟随玩家:
bash
CameraLinkerSmoothFollow linker =
mBattleCamera.linkTarget(
typeof(CameraLinkerSmoothFollow),
player) as CameraLinkerSmoothFollow;
linker.setRelativePosition(
new Vector3(0.0f, 6.0f, -8.0f));
linker.setLookAtOffset(
new Vector3(0.0f, 1.5f, 0.0f));
linker.setLookAtTarget(true);
linker.setNormalSpeed(5.0f);
linker.applyRelativePosition(
linker.getRelativePosition());
连接器默认在 LateUpdate 中更新,可以减少目标移动后摄像机延迟跟随产生的抖动。
停止跟随:
bash
mBattleCamera.unlinkTarget();
五、平滑修改 FOV
FOV 变化接入了关键帧系统:
bash
CmdGameCameraFOV.execute(
mBattleCamera,
0.25f,
0.0f,
mBattleCamera.getFOVY(),
40.0f,
KEY_CURVE.QUAD_OUT);
可以用于冲刺扩大视野、瞄准缩小视野和剧情镜头拉近。
正交摄像机则可以使用 CmdGameCameraOrthoSize 平滑改变显示范围。
六、URP Camera Stack
启用 URP 时,createCamera() 会读取摄像机的 RenderType。
如果创建的是 Overlay 摄像机,框架会按照 overlayCameraDepth 排序,并默认加入主摄像机的 Camera Stack:
bash
GameCamera sceneUICamera =
mCameraManager.createCamera(
sceneUICameraObject,
10);
Base 与 Overlay 摄像机必须位于同一个 Unity Scene。
用于 RenderTexture 的摄像机通常不需要 UI Stack,创建时应关闭自动添加:
bash
GameCamera previewCamera =
mCameraManager.createCamera(
previewCameraObject,
0,
true,
false);
七、AudioListener 自动管理
Unity 场景中只能有一个启用的 AudioListener。
CameraManager 按以下顺序选择:
bash
当前主摄像机
↓
UI 摄像机
↓
第一个激活的摄像机
切换摄像机时,业务层不需要逐个修改 AudioListener。
八、总结
CameraManager 负责摄像机的创建、销毁、主摄像机切换、URP Stack 和 AudioListener。
GameCamera 负责摄像机参数、坐标转换、目标跟随、关键帧变化和 RenderTexture。
这样场景切换、角色跟随、UI 叠加和镜头演出都能使用同一套生命周期,不需要让每个系统直接操作 Unity Camera。