资源来源:[Unity] 存档系统 Part 1 | PlayerPrefs | Unity初学者系列教程 | 数据存取 | 存档读档 | Save&Load_哔哩哔哩_bilibili
目录
1.PlayerPrefs
优缺点
适用于
示例
和1相比
用法
体会
1.PlayerPrefs
Unity引擎内建主要用来存储玩家偏好的类。
优缺点
优点:简单,容易使用
缺点:
1.存储复杂数据困难
2.存储数据类型有限
适用于
暂时性数据
玩家偏好
示例
在检查器中修改玩家数据的暴露变量后。点击保存,存储当前文本框的信息。
重启游戏。点击读档,读取上次保存的信息。
1.创建UI界面
文本框、按钮、背景图
2.编写玩家数据类和UI控制类的脚本
玩家数据类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerData : MonoBehaviour
{
#region Fields
//用户名
[SerializeField] string PlayerName = "斯卡蒂000";
//等级
[SerializeField] int PlayerLevel = 300;
//金币
[SerializeField] int PlayerCoins = 2000;
#endregion
#region Properties
public string Name => PlayerName;
public int level => PlayerLevel;
public int Coin => PlayerCoins;
public Vector3 Position => transform.position;
#endregion
public void Save() {
SaveByPlayerPrefs();
}
public void Load() {
LoadFromPlayerFrefs();
}
void SaveByPlayerPrefs()
{
PlayerPrefs.SetString("PlayerName", PlayerName);
PlayerPrefs.SetInt("PlayerLevel", PlayerLevel);
PlayerPrefs.SetInt("PlayerCoins", PlayerCoins);
}
void LoadFromPlayerFrefs()
{
PlayerName = PlayerPrefs.GetString("PlayerName");
PlayerLevel = PlayerPrefs.GetInt("PlayerLevel");
PlayerCoins = PlayerPrefs.GetInt("PlayerCoins");
}
}
UI控制类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UIControler : MonoBehaviour
{
[Header("-Texts-")]
[SerializeField] Text PlayerNameText;
[SerializeField] Text PlayerLevelText;
[SerializeField] Text PlayerCoinText;
[SerializeField] Text PlayerPositionText_X;
[Header("-Button-")]
[SerializeField] Button buttonSave;
[SerializeField] Button buttonLoad;
[Header("-PLayer Data-")]
//用户数据类
[SerializeField] PlayerData playerData;
void Start()
{
//点击按钮直接调用后面的方法
buttonSave.onClick.AddListener(() => playerData.Save());
buttonLoad.onClick.AddListener(() => playerData.Load());
}
// Update is called once per frame
void Update()
{
PlayerNameText.text = playerData.Name;
PlayerLevelText.text = playerData.level.ToString();
PlayerCoinText.text = playerData.Coin.ToString();
PlayerPositionText_X.text = playerData.Position.x.ToString("0.00");
}
}
3.添加脚本
添加一个空物体用来实例化玩家数据类脚本,并将UI控制类脚本挂载到UI画布上。
4.测试方法
在空对象挂载的玩家数据中 ,修改暴露变量的值,点击Game界面的保存。重启游戏,点击读档,即可看到画面显示的是修改后的值。(数据在点击保存后存储到了注册表中。)
2.Json-PlayerPrefs
和1相比
引入了json的概念。作为PlayerPrefs的拓展。
用法
在PlayerPrefs使用示例的基础上新增一个静态类savesystem。
静态类savesystem功能有三:
1.保存
2.读档
3.删档
PlayerData类中,复制了一遍玩家的基本信息,称savedata类。作为json数据传输用。
该类在声明时需要添加(下)
[System.Serializable]
作用:与json序列化和反序列化,解析有关。
(114条消息) Unity中[System.Serializable]作用-CSDN博客
流程运作:
保存:
1.UI控制器类监听到用户有保存数据操作,会调用PlayerData类的使用存储函数SaveByPlayerPrefs。
2.存储函数SaveByPlayerPrefs会临时new一个json传输类savedata,将要存储的信息装到savedata里面。
2. var p = new SaveData(); p.PlayerName = PlayerName; p.PlayerLevel = PlayerLevel; p.PlayerCoins = PlayerCoins; p.PlayPosition = Position; SaveSystem.SaveByPlayerPrefs(KEY_PLAYER_DATA, p);
3.再将savedata传输给静态类SaveSystem的SaveByPlayerPrefs方法,该方法会用JsonUtility.ToJson将savedata转换为json(var接收转换后结果)。
4.PlayerPrefs.SetString(键值,var)存储。
(5.键值是自己设计的常量)
读档:
1.UI控制器类监听到用户读档数据,调用PlayerData类的使用读档函数(LoadFromPlayerFrefs)。
2.读档函数通过键值从静态类SaveSystem的LoadFromPlayerPrefs中获取数据。
3.利用var接收获取数据的结果(因为存储的是json,所以返回的是json)。将var反转换成类。
var json= SaveSystem.LoadFromPlayerPrefs(KEY_PLAYER_DATA); var mes = JsonUtility.FromJson<SaveData>(json);
4.PlayerData的值重新赋值一遍。因为UI控制类的玩家数据的刷新操作是每帧,所以读档操作会以极快的速度显示出来。
示例
使用方法无改变
UI控制类无改变
玩家数据类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerData : MonoBehaviour
{
private const string KEY_PLAYER_DATA = "Key_PlayerData";
#region Fields
//用户名
[SerializeField] string PlayerName = "斯卡蒂000";
//等级
[SerializeField] int PlayerLevel = 300;
//金币
[SerializeField] int PlayerCoins = 2000;
#endregion
[System.Serializable]class SaveData
{
public string PlayerName;
public int PlayerLevel;
public int PlayerCoins;
public Vector3 PlayPosition;
}
#region Properties
public string Name => PlayerName;
public int level => PlayerLevel;
public int Coin => PlayerCoins;
public Vector3 Position => transform.position;
#endregion
public void Save() {
SaveByPlayerPrefs();
}
public void Load() {
LoadFromPlayerFrefs();
}
void SaveByPlayerPrefs()
{
/* PlayerPrefs.SetString("PlayerName", PlayerName);
PlayerPrefs.SetInt("PlayerLevel", PlayerLevel);
PlayerPrefs.SetInt("PlayerCoins", PlayerCoins);*/
var p = new SaveData();
p.PlayerName = PlayerName;
p.PlayerLevel = PlayerLevel;
p.PlayerCoins = PlayerCoins;
p.PlayPosition = Position;
SaveSystem.SaveByPlayerPrefs(KEY_PLAYER_DATA, p);
}
void LoadFromPlayerFrefs()
{
/*PlayerName = PlayerPrefs.GetString("PlayerName");
PlayerLevel = PlayerPrefs.GetInt("PlayerLevel");
PlayerCoins = PlayerPrefs.GetInt("PlayerCoins");*/
var json= SaveSystem.LoadFromPlayerPrefs(KEY_PLAYER_DATA);
var mes = JsonUtility.FromJson<SaveData>(json);
PlayerName = mes.PlayerName;
PlayerLevel = mes.PlayerLevel;
PlayerCoins = mes.PlayerCoins;
transform.position = mes.PlayPosition;
}
}
静态类savesystem
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public static class SaveSystem//静态类
{
public static void SaveByPlayerPrefs(string key,object data)
{
var json = JsonUtility.ToJson(data);//数据转json类型
PlayerPrefs.SetString(key, json);
PlayerPrefs.Save();
}
public static string LoadFromPlayerPrefs(string key)
{
return PlayerPrefs.GetString(key,null);
}
[UnityEditor.MenuItem("GAME——SAVE/游戏存档相关")]//静态函数才能生效
public static void DeletePlayerPrefs()
{
PlayerPrefs.DeleteAll();
//PlayerPrefs.DeleteKey("xxx");删除指定键
}
}
体会
1.=》使用
1.按钮按下调用可以调用跨类的方法,很好用,更简便
//点击按钮直接调用后面的方法
buttonSave.onClick.AddListener(() => playerData.Save());
2.赋值,将后面赋值给前面
每次调用Position会执行返回transform.position的操作。(get操作)
public Vector3 Position => transform.position;
2.暴露变量“标题”和“项”
Header 标头
SerializeField 序列化字段
[Header("-Texts-")]
[SerializeField] Text PlayerNameText;
3.Unity编辑界面菜单功能设计
前提:调用的函数为静态函数
样式:
[UnityEditor.MenuItem("GAME——SAVE/游戏存档相关")]//静态函数才能生效
public static void DeletePlayerPrefs()
{
PlayerPrefs.DeleteAll();
//PlayerPrefs.DeleteKey("xxx");删除指定键
}
“/”左边是功能栏,右边是下拉菜单的功能。
4.序列化SerializeField和public的区别
public看不到private,而SerializeField能在检查器中看到。
(114条消息) Unity3D中Public和[SerializeField]的使用_public serializefiel_conjee.的博客-CSDN博客