Cocos Creator 多场景共享数据全套方案
Cocos Creator 3.8.8 多场景共享数据全套方案(分轻量/全局/持久化,适配你的软体、液体物理项目)
核心场景需求
- 切换场景(关卡A→关卡B)保留:液体粒子数量、肉块软体参数、玩家设置、物理配置、道具数据
- 场景并行叠加(additive叠加场景)互相读写数据
- 重启游戏数据不丢失(持久存储)
- 区分:临时运行时共享 / 本地永久保存
方案1:全局单例类(最推荐,运行时全局共享,所有场景通用)
原理
创建静态单例管理类,脚本挂载在「常驻根节点」(不会随场景销毁),所有场景直接导入调用,存液体、肉块、玩家、物理全局配置。
步骤1:创建全局数据管理器 GlobalData.ts
// assets/Script/GlobalData.ts
import { _decorator } from 'cc';
const { ccclass } = _decorator;
// 全局数据结构,统一管理所有跨场景数据
export type GameData = {
// 你的软体肉块配置
meatSoftConfig: {
springFreq: number,
damping: number
},
// 液体物理参数
liquidConfig: {
viscosity: number,
dropCount: number
},
// 玩家通用数据
playerScore: number,
unlockLevel: number
}
@ccclass('GlobalData')
export class GlobalData {
// 单例静态实例
private static _instance: GlobalData;
public static get instance() {
if (!GlobalData._instance) {
GlobalData._instance = new GlobalData();
}
return GlobalData._instance;
}
// 全局存储仓库
public data: GameData = {
meatSoftConfig: { springFreq: 3.5, damping: 0.5 },
liquidConfig: { viscosity: 0.3, dropCount: 0 },
playerScore: 0,
unlockLevel: 1
}
// 快捷修改数据方法
setMeatSoft(freq: number, damp: number) {
this.data.meatSoftConfig.springFreq = freq;
this.data.meatSoftConfig.damping = damp;
}
addLiquidDrop(num: number) {
this.data.liquidConfig.dropCount += num;
}
// 清空临时运行数据(切换关卡重置用)
clearTempData() {
this.data.liquidConfig.dropCount = 0;
}
}步骤2:保证脚本常驻,任意场景读写
任意场景脚本读取/修改数据示例
import { GlobalData } from './GlobalData';
// 读取肉块软体参数
const softCfg = GlobalData.instance.data.meatSoftConfig;
console.log('当前软度', softCfg.springFreq);
// 修改液体粘度,切换下一个场景依然保留
GlobalData.instance.data.liquidConfig.viscosity = 0.8;
// 切换场景API(场景加载后数据不变)
director.loadScene("Level2");关键:为什么不会被场景销毁?
这个类是纯TS逻辑类,不绑定任何节点,不依附场景,只要游戏进程不关闭,数据永久存在。
适合:关卡切换、多场景共用物理配置、软体/液体全局参数。
方案2:常驻节点(PersistRoot,带组件逻辑共享)
如果你不仅要存数据,还要全局持续运行脚本(全局液体发射器、全局物理检测、全局计时器),用常驻节点。
- 在初始启动场景创建空节点
GameRoot 挂载代码:
director.addPersistRootNode(this.node)import { _decorator, Component, director } from 'cc'; const { ccclass } = _decorator; @ccclass('GameRoot') export class GameRoot extends Component { // 这里可以放全局数据 + 全局持续逻辑(液体全局生成、物理全局控制) public liquidTotal = 0; onLoad() { // 设置节点跨场景常驻,切换场景不会销毁 director.addPersistRootNode(this.node); } }任意场景获取常驻节点:
const root = director.getScene().getChildByName("GameRoot")!.getComponent(GameRoot); root.liquidTotal += 10;适用场景:需要全局持续运行的物理、特效管理器。
方案3:附加式场景(Additive 叠加场景,互相直接访问节点数据)
如果你不是销毁切换场景,而是多层场景同时显示(UI场景 + 物理关卡场景并行):
// 加载叠加场景,两个场景同时存在,节点互通
director.loadScene("UIScene", { additive: true });特点:
- 两个场景节点树共存,可以直接
find()另一个场景的节点、组件读取数据; - 缺点:场景多了层级混乱,不适合频繁切换关卡。
方案4:本地持久化存储(游戏关闭再打开依然保留数据)
上面两种只保内存,游戏关闭数据清空;需要永久存档用 sys.localStorage,搭配全局单例封装。
扩展全局单例,增加存档/读档
// 写入本地存档
saveToLocal() {
const str = JSON.stringify(this.data);
sys.localStorage.setItem("game_save", str);
}
// 启动读取存档
loadFromLocal() {
const str = sys.localStorage.getItem("game_save");
if(str) {
this.data = JSON.parse(str);
}
}使用时机:关卡完成调用 saveToLocal();游戏启动第一帧调用 loadFromLocal()。
四、四种方案对比,按需选择
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 纯TS单例GlobalData | 最轻量、无节点依赖、读写极快 | 不能挂载持续运行的组件 | 90%项目,跨场景共享配置、数值(肉块/液体参数首选) |
| 常驻Persist节点 | 可运行全局脚本、全局物理/特效管理器 | 多常驻节点容易混乱 | 需要全局持续逻辑(全局液体生成器、全局碰撞检测) |
| Additive叠加场景 | 直接访问跨场景节点 | 内存占用高,场景销毁麻烦 | UI与游戏场景分层、双场景同时显示 |
| localStorage持久化 | 永久保存,重启游戏不丢失 | 只能存简单JSON,不能存对象/节点 | 存档、玩家设置、解锁内容 |
五、实战避坑重点(踩坑总结)
- 不要把场景内节点、RigidBody、粒子放进全局数据
切换场景后原场景节点会被销毁,保存引用会报错、内存泄漏;只存数值、配置参数,不存场景实体。
正确:存液体粘度数字、弹簧刚度数值
错误:存肉块质点Node、水滴预制体实例 多场景同时修改同一全局数据,数据冲突处理
复杂项目加事件分发EventTarget,数据修改发送事件,所有场景监听自动刷新:import { EventTarget } from 'cc'; export const gameEvent = new EventTarget(); // 修改数据后派发事件 GlobalData.instance.setMeatSoft(4,0.6); gameEvent.emit("meatConfigChange"); // 其他场景监听数据更新 gameEvent.on("meatConfigChange", ()=>{ // 重新更新肉块软体弹簧参数 })- 切换场景清空临时数据
每进新关卡执行GlobalData.instance.clearTempData(),清除本关卡临时液体粒子计数,保留全局解锁、设置。 - 物理资源跨场景复用
预制体(水滴、肉块)不要每个场景重复加载,在启动场景一次性加载存入全局单例,所有场景复用,减少卡顿。
六、你的软体/液体项目推荐组合(最优解)
- 基础:纯TS全局单例 GlobalData 存储所有软体、液体物理参数、玩家数据
- 全局特效:创建一个 Persist 常驻节点,挂载全局液体粒子管理器,全程生成水滴不中断
- 存档功能:单例封装 localStorage 实现配置永久保存
- 数据同步:搭配 EventTarget 事件,修改参数后自动刷新场景内所有肉块、液体物理效果
版权属于:Joyber
本文链接:https://blog.qqvbc.com/default/1496.html
转载时须注明出处及本声明