Unity-数据持久化-PlayerPrefs

  • Post author:
  • Post category:其他


一、数据持久化概念

数据持久化就是将内存中的数据模型转换为存储模型,以及将存储模型转换为内存中的数据模型的统称。

简单来说:就是将游戏数据存储到硬盘,将硬盘中数据读取到游戏中,也就是传统意义上的存盘。

是Unity提供的可以用于存储读取玩家数据的公共类。

二、PlayerPrefs

(一)PlayerPrefs的基本方法

1.存储相关

PlayerPrefs的数据存储 类似于键值对存储 一个键对应一个值

提供了存储3中数据的方法 int  float  string

键:string类型

值:int  float  string  对应3种API

直接

PlayerPrefs.SetInt(“myAge”, 18);//存入内存

PlayerPrefs.SetFloat(“myHeight”, 229.5f);

PlayerPrefs.SetString(“myName”, “姚明”);

直接调用Set相关方法 只会把数据存到内存中

当游戏结束时 Unity会自动把数据存到硬盘中

如果游戏报错崩溃,数据不会存到硬盘中

PlayerPrefs.Save();

调用该方法,会马上存储到硬盘中

局限性:只能存3种类型数据

若想存储其他,只能降低会提高精度来存储

布尔类型

bool sex = true;

PlayerPrefs.SetInt(“sex” , sex ?  1  :  0);

如果类型用同一键名存储,会覆盖

PlayerPrefs.SetFloat(“myAge”,20.2f);

2.读取相关

运行时,只要Set对应键值对,即使没有马上Save到本地,也可以读取信息

int age = PlayerPrefs.GetInt(“myAge”);//如果找不到 返回默认值0

age = PlayerPrefs.GetInt(“myAge”  , 100 );

如果找不到myAge对应的值,就会返回函数的第二个参数 默认值

float height = PlayerPrefs.GetFloat(“myHeight” , 1000f);

float name= PlayerPrefs.GetString(“myname” , “姚明”);

判断数据是否存在

PlayerPrefs.HasKey(“myName”);

3.删除数据

删除指定键值对

PlayerPrefs.DeleteKey();

删除所有存储的信息

PlayerPrefs.DeleteAll();

4.练习1

现在有玩家信息类,有名字,年龄,攻击力,防御力等成员。另有装备信息类,装备类中有id,数量两个成员。

现在为其封装两个方法,一个用来存储数据,一个用来读取数据

注意,装备是个list,所以存储时候需要遍历

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Item
{
    public int id;
    public int num;
}

public class Player
{
    public string name;
    public int age;
    public int atk;
    public int def;
    //拥有的装备信息
    public List<Item> itemList;

    //这个变量 是一个 存储和读取的一个唯一key标识
    private string keyName;

    /// <summary>
    /// 存储数据
    /// </summary>
    public void Save()
    {
        PlayerPrefs.SetString(keyName +"_name", name);
        PlayerPrefs.SetInt(keyName + "_age", age);
        PlayerPrefs.SetInt(keyName + "_atk", atk);
        PlayerPrefs.SetInt(keyName + "_def", def);
        //存储有多少个装备
        PlayerPrefs.SetInt(keyName + "_ItemNum", itemList.Count);
        for (int i = 0; i < itemList.Count; i++)
        {
            //存储每一个装备的信息
            PlayerPrefs.SetInt(keyName + "_itemID" + i, itemList[i].id);
            PlayerPrefs.SetInt(keyName + "_itemNum" + i, itemList[i].num);
        }

        PlayerPrefs.Save();
    }
    /// <summary>
    /// 读取数据
    /// </summary>
    public void Load(string keyName)
    {
        //记录你传入的标识
        this.keyName = keyName;

        name = PlayerPrefs.GetString(keyName + "_name", "未命名");
        age = PlayerPrefs.GetInt(keyName + "_age", 18);
        atk = PlayerPrefs.GetInt(keyName + "_atk", 10);
        def = PlayerPrefs.GetInt(keyName + "_def", 5);

        //得到有多少个装备
        int num = PlayerPrefs.GetInt(keyName + "_ItemNum", 0);
        //初始化容器
        itemList = new List<Item>();
        Item item;
        for (int i = 0; i < num; i++)
        {
            item = new Item();
            item.id = PlayerPrefs.GetInt(keyName + "_itemID" + i);
            item.num = PlayerPrefs.GetInt(keyName + "_itemNum" + i);
            itemList.Add(item);
        }
    }
}

public class Lesson1_Exercises : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {

        //现在有玩家信息类,有名字,年龄,攻击力,防御力等成员
        //现在为其封装两个方法,一个用来存储数据,一个用来读取数据

        //Player p = new Player();
        //p.Load();
        //print(p.name);
        //print(p.age);
        //print(p.atk);
        //print(p.def);

        //p.name = "唐老狮";
        //p.age = 22;
        //p.atk = 40;
        //p.def = 10;
        改了过后存储
        //p.Save();

 

        Player p = new Player();
        p.Load("Player1");
        p.Save();

        Player p2 = new Player();
        p2.Load("Player2");
        p.Save();
        //装备信息
        //print(p.itemList.Count);
        //for (int i = 0; i < p.itemList.Count; i++)
        //{
        //    print("道具ID:" + p.itemList[i].id);
        //    print("道具数量:" + p.itemList[i].num);
        //}

        为玩家添加一个装备
        //Item item = new Item();
        //item.id = 1;
        //item.num = 1;
        //p.itemList.Add(item);
        //item = new Item();
        //item.id = 2;
        //item.num = 2;
        //p.itemList.Add(item);

    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

(二)PlayerPrefs在不同平台的存储位置

1.不同平台存储位置不同

Window

//PlayerPrefs存储在

// HKCU\Software\[公司名称]\产品名称]项下的注册表中

//其中公司和产品名称是在“Project settings”中设置的名称。

//运行regedit

//HKEY_CURRENT_USER/ /SOFTWARE

//Unity

//UnityEditor//公司名称//产品名称

Android

/data/data/包名/shared_prefs/pkg-name.xml

IOS

/Library/Preferences/[应用ID].plist

2.PlayerPrefs数据唯一性

//PlayerPrefs中不同数据的唯一性

//是由key决定的,不同的key决定了不同的数据

//同一项目中 如果不同数据key相同 会造成数据丢失

//要保证数据不丢失就要建立一个保证key唯一的规则

3.练习2

要在游戏中做一个排行榜功能,排行榜主要记录玩家名(可重复),玩家得分,玩家通关时间,请用PlayerPrefs存储读取排行榜相关信息

注意:这个名字可以重复就代表了不能单独的将名字当做key

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 排行榜具体信息
/// </summary>
public class RankListInfo
{
    public List<RankInfo> rankList;

    public RankListInfo()
    {
        Load();
    }

    /// <summary>
    /// 新加排行榜信息
    /// </summary>
    public void Add(string name , int score, int time)
    {
        rankList.Add(new RankInfo(name, score, time));
    }

    public void Save()
    {
        //存储有多少条数据
        PlayerPrefs.SetInt("rankListNum", rankList.Count);
        for (int i = 0; i < rankList.Count; i++)
        {
            RankInfo info = rankList[i];
            PlayerPrefs.SetString("rankInfo" + i, info.playerName);
            PlayerPrefs.SetInt("rankScore" + i, info.playerScore);
            PlayerPrefs.SetInt("rankTime" + i, info.playerTime);
        }
    }

    private void Load()
    {
        int num = PlayerPrefs.GetInt("rankListNum", 0);
        rankList = new List<RankInfo>();
        for (int i = 0; i < num; i++)
        {
            RankInfo info = new RankInfo(PlayerPrefs.GetString("rankInfo" + i),
                                          PlayerPrefs.GetInt("rankScore" + i),
                                          PlayerPrefs.GetInt("rankTime" + i));
            rankList.Add(info);
        }
    }
}

/// <summary>
/// 排行榜单条信息
/// </summary>
public class RankInfo
{
    public string playerName;
    public int playerScore;
    public int playerTime;

    public RankInfo(string name, int score, int time)
    {
        playerName = name;
        playerScore = score;
        playerTime = time;
    }
}

public class Lesson2_Exercises : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        #region 练习题一 
        //将知识点一中的练习题,改为可以支持存储多个玩家信息
        #endregion

        #region 练习题二
        //要在游戏中做一个排行榜功能
        //排行榜主要记录玩家名(可重复),玩家得分,玩家通关时间
        //请用PlayerPrefs存储读取排行榜相关信息

        RankListInfo rankList = new RankListInfo();
        print(rankList.rankList.Count);
        for (int i = 0; i < rankList.rankList.Count; i++)
        {
            print("姓名" + rankList.rankList[i].playerName);
            print("分数" + rankList.rankList[i].playerScore);
            print("时间" + rankList.rankList[i].playerTime);
        }

        rankList.Add("唐老狮", 100, 99);
        rankList.Save();
        #endregion
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

(三)利用反射结合PlayerPrefs制作通用存储工具



版权声明:本文为weixin_53163894原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。