结合easysave的存档系统

using System.Collections.Generic;
using BaiShiStudio.DeadDog.Interface;
using QFramework;
using UnityEngine;

namespace BaiShiStudio.DeadDog
{
    public class PlayerModel : AbstractModel, ISavable
    {
        public readonly BindableProperty<float> MaxHealth = new();
        
        public readonly BindableProperty<float> CurrentHealth = new();
        
        public readonly List<BindableProperty<float>> EnergyBlocks = new();
        
        public readonly BindableProperty<Vector2> LastPositionOnGround = new();
        
        public readonly BindableProperty<bool> HasShadowTeleport = new();
        
        public readonly BindableProperty<bool> HasAttack = new();
        
        public readonly BindableProperty<bool> HasThrow = new();
        
        protected override void OnInit()
        {
            MaxHealth.Value = PlayerDataDefinition.Instance.MaxHealth;
            
            CurrentHealth.Value = MaxHealth.Value;
            
            EnergyBlocks.Clear();
            
            for (int i = 0; i < PlayerDataDefinition.Instance.MaxEnergyBlocks; i++)
            {
                EnergyBlocks.Add(new BindableProperty<float>(PlayerDataDefinition.Instance.EnergyPerBlock));
            }
        }

        public void Save()
        {
            //ES3.Save("PlayerModel.CurrentHealth", CurrentHealth.Value);
            ES3.Save("PlayerModel.LastPositionOnGround", LastPositionOnGround.Value);
            ES3.Save("PlayerModel.HasShadowTeleport", HasShadowTeleport.Value);
            ES3.Save("PlayerModel.HasAttack", HasAttack.Value);
            ES3.Save("PlayerModel.HasThrow", HasThrow.Value);
        
        }

        public void Load()
        {
            LastPositionOnGround.Value = ES3.Load("PlayerModel.LastPositionOnGround", LastPositionOnGround.Value);
            HasShadowTeleport.Value = ES3.Load("PlayerModel.HasShadowTeleport", false);
            HasAttack.Value = ES3.Load("PlayerModel.HasAttack", false);
            HasThrow.Value = ES3.Load("PlayerModel.HasThrow", false);
            MaxHealth.Value = PlayerDataDefinition.Instance.MaxHealth;
            // 血量恢复满
            CurrentHealth.Value = MaxHealth.Value;

            // 恢复最后地面位置
            LastPositionOnGround.Value = ES3.Load("PlayerModel.LastPositionOnGround", LastPositionOnGround.Value);

            // 能量格充满
            for (int i = 0; i < PlayerDataDefinition.Instance.MaxEnergyBlocks; i++)
            {
                EnergyBlocks.Add(new BindableProperty<float>(PlayerDataDefinition.Instance.EnergyPerBlock));
            }

        }
        public void NewGame()
        {
            CurrentHealth.Value = MaxHealth.Value;
            HasShadowTeleport.Value = false;
            HasAttack.Value =false;
            HasThrow.Value = false;
        }
    }
}

PlayerModel里面存储数据

使用方法:

private PlayerModel model;
 private void Awake()
    {
        model = DeadDogArchitecture.Interface.GetModel<PlayerModel>();
    }
// 恢复数据
        model.Load();

地图存档系统

using System.Collections;
using System.Collections.Generic;
using BaiShiStudio.DeadDog.Interface;
using UnityEngine;

public class MapManager : MonoBehaviour, ISavable
{
    // 单例实例
    private static MapManager _instance;

    // 用来记录哪些房间已经解锁的字典(房间ID -> 是否已解锁)
    private Dictionary<string, bool> _unlockedRooms = new();

    // 用来存储场景中的房间对象
    private MapContainerData[] _rooms;

    // 单例模式
    public static MapManager Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = new MapManager(); // 确保 MapManager 在第一次调用时被实例化
            }
            return _instance;
        }
    }

    // 在 Awake 中初始化
    private void Awake()
    {
        // 这里确保 `MapManager` 只会有一个实例
        if (_instance == null)
        {
            _instance = this;
        }
        // 获取场景中所有房间的 MapContainerData 组件
        _rooms = GetComponentsInChildren<MapContainerData>(true);
    }
    

    // 查询某个房间是否已经解锁
    public bool IsRoomUnlocked(string roomId)
    {
        return _unlockedRooms.TryGetValue(roomId, out bool unlocked) && unlocked;
    }

    // 存档函数:将所有已解锁房间保存到磁盘(使用 ES3)
    public void Save()
    {
        // 清空旧的数据,避免存储错误的旧值
        _unlockedRooms.Clear();

        // 遍历场景中的所有房间
        foreach (var room in _rooms)
        {
            bool revealed = room.HasBeenRevealed; // 判断房间是否已经被解锁
            string id = room.RoomId; // 获取房间的ID
            if (!string.IsNullOrEmpty(id))
            {
                // 将房间的解锁状态存储到字典和磁盘
                _unlockedRooms[id] = revealed;
                // 输出保存的房间ID和解锁状态
                Debug.Log($"Saving Room ID: {id}, Revealed: {revealed}");
                
                ES3.Save($"Map.Room.{id}", revealed);
            }
        }
    }

    // 读档函数:从磁盘读取之前保存的解锁状态
    public void Load()
    {
        _unlockedRooms.Clear();

        // 获取所有房间的ID
        var allRoomIds = MapUtils.GetAllRoomIds();

        // 读取每个房间的解锁状态
        foreach (var id in allRoomIds)
        {
            bool unlocked = ES3.Load($"Map.Room.{id}", false);
            if (unlocked)
            {
                _unlockedRooms[id] = true;
            }
        }

        // 顺便刷新场景里的房间显示状态
        foreach (var room in _rooms)
        {
            room.HasBeenRevealed = IsRoomUnlocked(room.RoomId);
            room.gameObject.SetActive(room.HasBeenRevealed); // 显示解锁的房间
        }
    }

    // 解锁并显示某个房间
    public void RevealRoomById(string roomId)
    {
        _unlockedRooms[roomId] = true;
        foreach (var room in _rooms)
        {
            if (room.RoomId == roomId && !room.HasBeenRevealed)
            {
                room.gameObject.SetActive(true); // 显示房间
                room.HasBeenRevealed = true;    // 标记房间已解锁
            }
        }
    }
}

使用方法:

using BaiShiStudio.DeadDog;
using UnityEngine;

public class CheckpointTrigger : MonoBehaviour
{
    [Header("Checkpoint")]
    public string spawnPointName; // 用于配合出生点
    [Header("RoomId")]
    public string roomId;
    public bool isSilent = false; // 是否静默触发(用于门口那种)

    private bool triggered = false;

    private void OnTriggerEnter2D(Collider2D other)
    {
        if (triggered) return;

        if (other.CompareTag("Player"))
        {
            ScenePortalData.Set(spawnPointName); // 设置下次出生点
            var playerModel = DeadDogArchitecture.Interface.GetModel<PlayerModel>();
            playerModel.LastPositionOnGround.Value = other.transform.position;
            playerModel.Save();
            triggered = true;
            MapManager.Instance.RevealRoomById(roomId);
            // 保存地图数据
            MapManager.Instance.Save();
        }
    }
}

这个mono类挂在场景的自动存档点里面

此文章会随着存档系统完善继续更新

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值