在 Cocos Creator(尤其是 Cocos Creator 3.x)开发中,管理跨场景使用的用户信息等全局变量,有几种推荐的做法。核心原则是避免滥用全局变量,同时保证数据的可维护性、可扩展性和安全性。
以下是几种常用且推荐的方式:
1. 使用单例(Singleton)管理器类
这是最常见和推荐的方式。
- 创建一个
UserDataManager或GameManager类作为单例。 - 将用户信息(如昵称、金币、等级、登录状态等)保存在这个单例中。
- 单例在整个游戏生命周期中只存在一份,不会随场景切换而销毁。
示例(TypeScript):
// UserDataManager.ts
export class UserDataManager {
private static _instance: UserDataManager;
public static get instance(): UserDataManager {
if (!this._instance) {
this._instance = new UserDataManager();
}
return this._instance;
}
private _userName: string = "";
private _gold: number = 0;
get userName() { return this._userName; }
set userName(value: string) { this._userName = value; }
get gold() { return this._gold; }
set gold(value: number) { this._gold = value; }
// 可选:初始化或从本地加载
init() {
// 例如从 localStorage 加载
const saved = localStorage.getItem("userData");
if (saved) {
const data = JSON.parse(saved);
this._userName = data.name || "";
this._gold = data.gold || 0;
}
}
saveToLocalStorage() {
localStorage.setItem("userData", JSON.stringify({
name: this._userName,
gold: this._gold
}));
}
}
在主场景(如启动场景)调用
UserDataManager.instance.init()初始化即可。
2. 结合持久化存储(如 localStorage / cc.sys.localStorage)
- 单例负责运行时数据管理;
- 配合
localStorage实现退出游戏后数据不丢失; - 注意敏感信息(如 token)不要明文存 localStorage,必要时加密或使用安全存储方案。
3. 使用 Cocos 的 EventTarget / director.emit 进行通信(辅助手段)
- 当用户数据变更时,可以通过事件通知其他模块更新 UI。
- 但不要用事件代替数据存储,事件只是通信机制。
// 数据变更时
UserDataManager.instance.gold += 100;
director.emit('userGoldChanged', UserDataManager.instance.gold);
// 其他组件监听
director.on('userGoldChanged', this.onGoldChanged, this);
4. 避免直接挂载到 window 或 globalThis
虽然可行(如 window.userData = {...}),但:
- 不利于类型检查(TS 中无提示);
- 容易命名冲突;
- 不符合模块化规范。
5. 对于复杂项目:考虑状态管理库(如 Redux-like 架构)
- 如果项目较大、状态复杂,可自研或引入轻量状态管理;
- Cocos 官方未强制绑定状态库,但可以自己实现类似 Flux/Redux 的模式。
总结建议:
| 场景 | 推荐方式 |
|---|---|
| 简单小游戏 | 单例 + localStorage |
| 中大型项目 | 单例 + 模块化 + 事件通信 |
| 多人在线/敏感数据 | 单例 + 后端同步 + 安全存储 |
⚠️ 注意:Cocos 场景切换时,非持久节点会被销毁。如果你把用户数据挂在某个节点上,记得将其设为
persistent(通过cc.game.addPersistRootNode()),但更推荐用纯逻辑单例而非依赖节点。