You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中如何使用单例模式实现跨场景传递CameraRig对象?

CameraRig跨场景单例的代码实现位置方案

核心原则:单例生命周期逻辑要和业务逻辑完全解耦,不要把单例代码混在相机控制、队伍管理的功能脚本里。

具体实现分层

  • 第一层(可选,推荐实现):抽一个通用的持久化单例泛型基类,所有需要跨场景存活的MonoBehaviour单例都可以复用这个基类,不用重复写相同的判断逻辑,代码示例如下:
// 这个脚本放在项目专门存通用工具/框架代码的目录即可,和具体业务无关
public class PersistentMonoSingleton<T> : MonoBehaviour where T : Component
{
    public static T Instance { get; private set; }

    protected virtual void Awake()
    {
        // 重复创建实例时直接销毁多余对象
        if (Instance != null && Instance != this)
        {
            Destroy(gameObject);
            return;
        }
        Instance = this;
        // 标记整个对象跨场景不销毁
        DontDestroyOnLoad(gameObject);
    }
}
  • 第二层:在你的CameraRig根对象上单独挂载一个轻量脚本,比如命名为CameraRigRoot,这个脚本只负责托管整个CameraRig对象的单例生命周期,不写任何相机控制、队伍切换的业务逻辑,只需要继承上面的泛型基类即可:
// 这个脚本仅挂在CameraRig根节点,和对象生命周期完全绑定
public class CameraRigRoot : PersistentMonoSingleton<CameraRigRoot>
{
    // 不需要写额外逻辑,基类已经处理完单例判断和跨场景保活
}
  • 第三层:你原来写的CameraController、TeamManager脚本完全不需要改动,保持原有的业务逻辑就行。其他脚本需要调用相机控制、队伍切换功能时,直接通过单例实例拿对应组件即可,比如:
// 其他业务逻辑里的调用示例
CameraController mainCamCtrl = CameraRigRoot.Instance.GetComponent<CameraController>();
TeamManager camTeamMgr = CameraRigRoot.Instance.GetComponent<TeamManager>();

避坑说明

不要把单例逻辑直接写在CameraController或者TeamManager这类业务脚本里:

  • 单例的生命周期是和整个CameraRig对象绑定的,不是和某个单独组件绑定的。如果把单例逻辑写在CameraController里,后续你如果需要临时加过场相机、也挂载CameraController组件做控制,会直接触发单例冲突,把原本持久化的主相机Rig销毁,排查问题成本很高。
  • 业务逻辑和生命周期逻辑混在一起,后续改功能的时候很容易不小心改坏单例判断逻辑,导致跨场景丢对象、多实例重复创建之类的问题。

简化方案

如果你的项目目前规模很小,只有CameraRig这一个需要跨场景持久化的对象,不想额外抽通用基类,也可以直接把单例判断、DontDestroyOnLoad的逻辑直接写在CameraRigRoot脚本里,不需要泛型基类,功能完全一致。

内容的提问来源于stack exchange,提问作者Pablo Gasamans Losada

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 20:01:03