Cocos Creator多场景数据共享:全局变量与单例模式
在Cocos Creator游戏开发中,场景切换时的数据共享是开发者面临的常见挑战。本文将详细介绍两种实用方案——全局变量与单例模式(Singleton Pattern),帮助你轻松实现跨场景数据传递,提升游戏开发效率。
一、全局变量方案:简单直接的共享方式
1.1 引擎内置全局对象
Cocos引擎提供了cclegacy全局对象,可直接用于存储跨场景数据。该对象定义在cocos/core/global-exports.ts中,代码如下:
// 引擎全局命名空间定义
export const cclegacy: Record<string, any> & {
_global: typeof globalThis;
} = {
_global,
};
// 挂载到全局对象
_global.cc = legacyCC;
通过cclegacy存储玩家数据的示例:
// 存储数据
cclegacy.playerData = {
score: 0,
level: 1,
items: []
};
// 在其他场景访问
console.log("当前分数:", cclegacy.playerData.score);
1.2 自定义全局模块
对于复杂项目,建议创建专用全局模块。在assets目录下新建GlobalData.ts:
// assets/GlobalData.ts
export const GlobalData = {
playerInfo: {
name: "玩家1",
hp: 100
},
gameSettings: {
musicVolume: 0.8,
soundVolume: 1.0
},
// 数据持久化方法
saveData() {
// 实现本地存储逻辑
}
};
在任意脚本中引用:
import { GlobalData } from "../assets/GlobalData";
// 修改数据
GlobalData.playerInfo.hp = 80;
二、单例模式:更优雅的状态管理
2.1 基础单例实现
单例模式确保一个类只有一个实例,并提供全局访问点。典型实现如下:
// assets/manager/GameManager.ts
class GameManager {
private static instance: GameManager;
// 私有构造函数防止外部实例化
private constructor() {}
// 全局访问点
public static getInstance(): GameManager {
if (!GameManager.instance) {
GameManager.instance = new GameManager();
}
return GameManager.instance;
}
// 游戏状态
public gameState: "idle" | "playing" | "paused" | "gameOver" = "idle";
// 场景切换时保持数据
public currentLevel: number = 1;
}
// 导出实例
export const gameManager = GameManager.getInstance();
2.2 结合组件的单例
在场景中挂载持久化组件,通过director获取:
// assets/components/GameController.ts
import { _decorator, Component, director } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('GameController')
export class GameController extends Component {
private static instance: GameController;
onLoad() {
// 场景切换时不销毁
director.addPersistRootNode(this.node);
if (!GameController.instance) {
GameController.instance = this;
} else {
// 防止重复创建
director.removePersistRootNode(this.node);
this.node.destroy();
}
}
// 游戏数据
public playerScore: number = 0;
// 数据操作方法
public addScore(points: number) {
this.playerScore += points;
console.log("加分:", points, "总分:", this.playerScore);
}
}
三、方案对比与最佳实践
3.1 两种方案的优缺点
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 全局变量 | 实现简单,访问直接 | 容易污染全局命名空间,大型项目难维护 | 小型项目,简单数据共享 |
| 单例模式 | 封装性好,有状态管理,可扩展 | 实现相对复杂,过度使用会导致代码耦合 | 中大型项目,核心管理器 |
3.2 性能与内存考量
- 避免在全局存储大量临时数据,建议使用
WeakMap存储临时对象 - 单例组件应在游戏结束时手动清理资源
- 复杂数据建议使用
cc.sys.localStorage进行持久化
3.3 引擎内置单例参考
Cocos引擎内部大量使用单例模式,例如:
四、常见问题解决
4.1 场景切换数据丢失
确保:
- 单例组件已添加到持久化节点:
director.addPersistRootNode(this.node) - 全局变量挂载在
cclegacy或自定义全局对象上 - 复杂数据使用本地存储API:
// 保存到本地存储
cc.sys.localStorage.setItem("playerData", JSON.stringify(GlobalData.playerInfo));
// 读取数据
const savedData = cc.sys.localStorage.getItem("playerData");
if (savedData) {
GlobalData.playerInfo = JSON.parse(savedData);
}
4.2 类型安全与代码提示
使用TypeScript接口增强类型安全:
interface PlayerInfo {
name: string;
level: number;
score: number;
}
// 定义带类型的全局数据
export const GlobalData = {
player: {} as PlayerInfo,
// ...
};
五、总结与扩展阅读
全局变量和单例模式是Cocos Creator中实现多场景数据共享的两种核心方案。全局变量适合简单场景,而单例模式提供了更好的封装性和可维护性。实际开发中,可根据项目规模和团队习惯选择合适方案。
官方文档:
进阶学习:
- 状态管理库集成(如Redux)
- 数据持久化最佳实践
- 模块化与代码分割
通过合理运用这些技术,你可以构建出结构清晰、易于维护的游戏项目,提升开发效率和游戏性能。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



