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类挂在场景的自动存档点里面


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

被折叠的 条评论
为什么被折叠?



