Cocos Creator 3.8.8 多场景共享数据全套方案(分轻量/全局/持久化,适配你的软体、液体物理项目)

核心场景需求

  1. 切换场景(关卡A→关卡B)保留:液体粒子数量、肉块软体参数、玩家设置、物理配置、道具数据
  2. 场景并行叠加(additive叠加场景)互相读写数据
  3. 重启游戏数据不丢失(持久存储)
  4. 区分:临时运行时共享 / 本地永久保存

方案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,带组件逻辑共享)

如果你不仅要存数据,还要全局持续运行脚本(全局液体发射器、全局物理检测、全局计时器),用常驻节点。

  1. 初始启动场景创建空节点 GameRoot
  2. 挂载代码: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);
     }
    }
  3. 任意场景获取常驻节点:

    const root = director.getScene().getChildByName("GameRoot")!.getComponent(GameRoot);
    root.liquidTotal += 10;

    适用场景:需要全局持续运行的物理、特效管理器。

方案3:附加式场景(Additive 叠加场景,互相直接访问节点数据)

如果你不是销毁切换场景,而是多层场景同时显示(UI场景 + 物理关卡场景并行):

// 加载叠加场景,两个场景同时存在,节点互通
director.loadScene("UIScene", { additive: true });

特点:

  1. 两个场景节点树共存,可以直接 find() 另一个场景的节点、组件读取数据;
  2. 缺点:场景多了层级混乱,不适合频繁切换关卡。

方案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,不能存对象/节点存档、玩家设置、解锁内容

五、实战避坑重点(踩坑总结)

  1. 不要把场景内节点、RigidBody、粒子放进全局数据
    切换场景后原场景节点会被销毁,保存引用会报错、内存泄漏;只存数值、配置参数,不存场景实体。
    正确:存液体粘度数字、弹簧刚度数值
    错误:存肉块质点Node、水滴预制体实例
  2. 多场景同时修改同一全局数据,数据冲突处理
    复杂项目加事件分发EventTarget,数据修改发送事件,所有场景监听自动刷新:

    import { EventTarget } from 'cc';
    export const gameEvent = new EventTarget();
    
    // 修改数据后派发事件
    GlobalData.instance.setMeatSoft(4,0.6);
    gameEvent.emit("meatConfigChange");
    
    // 其他场景监听数据更新
    gameEvent.on("meatConfigChange", ()=>{
     // 重新更新肉块软体弹簧参数
    })
  3. 切换场景清空临时数据
    每进新关卡执行 GlobalData.instance.clearTempData(),清除本关卡临时液体粒子计数,保留全局解锁、设置。
  4. 物理资源跨场景复用
    预制体(水滴、肉块)不要每个场景重复加载,在启动场景一次性加载存入全局单例,所有场景复用,减少卡顿。

六、你的软体/液体项目推荐组合(最优解)

  1. 基础:纯TS全局单例 GlobalData 存储所有软体、液体物理参数、玩家数据
  2. 全局特效:创建一个 Persist 常驻节点,挂载全局液体粒子管理器,全程生成水滴不中断
  3. 存档功能:单例封装 localStorage 实现配置永久保存
  4. 数据同步:搭配 EventTarget 事件,修改参数后自动刷新场景内所有肉块、液体物理效果

标签: none

添加新评论