当前位置: 首页 > news >正文

数据持久化--PlayerPrefs

PlayerPrefs是什么

在 Unity 中,PlayerPrefs 是一个用于存储和读取游戏偏好设置(如音量、最高分、游戏进度等)的内置类。它提供了一种简单的键值对存储方式,支持三种基本数据类型:intfloat 和 string,并会将数据持久化到本地文件系统。

支持的数据类型

PlayerPrefs 直接支持三种基础数据类型(底层都是存储为字符串):

  1. ​int (整型):​​ PlayerPrefs.SetInt(string key, int value);
  2. ​float (浮点型):​​ PlayerPrefs.SetFloat(string key, float value);
  3. ​string (字符串):​​ PlayerPrefs.SetString(string key, string value);

存储相关

PlayerPrefs.GetInt("myAge", 18);
PlayerPrefs.GetFloat("myFloat", 177.8f);
PlayerPrefs.GetString("myName", "DamnF");
//直接调用Set方法,只会把数据存储到内存中
//当游戏结束时 Unity会自动把数据存到硬盘中
//如果游戏不是正常结束 而是崩溃 数据是不会存到硬盘中的PlayerPrefs.Save();
//只要调用该方法 就会马上存到硬盘中

PlayerPrefs具有局限性,只能存储三种类型数据,如果想存别的,只能降低精度 或上升精度来存储

存储bool类型:

bool sex = true;
PlayerPrefs.GetInt("sex", sex ? 1 : 0);

如果不同类型用同一键名进行存储 会进行覆盖

读取相关

 int age = PlayerPrefs.GetInt("myAge");float height = PlayerPrefs.GetFloat("myHeight", 1000f);//如果找不到myHeight的值,会把第二个参数1000f作为默认值传入方法显示string name = PlayerPrefs.GetString("myName");

判读数据是否存在

if(PlayerPrefs .HasKey ("myName"))
{print("存在对应的键值对数据");
}

删除数据相关

 //删除指定键值对PlayerPrefs.DeleteKey("myAge");//删除所有键值对PlayerPrefs.DeleteAll();

练习题

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> items;public void Save(){PlayerPrefs.SetString("name", name);PlayerPrefs.SetInt("age", age);PlayerPrefs.SetInt("atk",atk);PlayerPrefs.SetInt("def", def);//存储多少个装备PlayerPrefs .SetInt ("ItemNum",items .Count);//存储每个装备for (int i = 0; i < items .Count ; i++){PlayerPrefs.SetInt("ItemID" + i, items[i].id);PlayerPrefs.SetInt("ItemNum" + i, items[i].num);}PlayerPrefs .Save ();}public void Load(){name= PlayerPrefs.GetString("name","未命名");age= PlayerPrefs.GetInt("age", 18);atk= PlayerPrefs.GetInt("atk", 11);def= PlayerPrefs.GetInt("def", 123);//得到多少个装备int num = PlayerPrefs.GetInt("ItemNum", 0);//初始化容器items = new List<Item>();Item item;for (int i = 0; i < num ; i++){item = new Item();item.id = PlayerPrefs.GetInt("ItemID" + i);item.num = PlayerPrefs.GetInt("ItemNum" + i);items .Add (item);}}
}
public class Lesson1_exericse : MonoBehaviour
{// Start is called before the first frame updatevoid Start(){//Player p=new Player ();//p.Load();//print(p.name);//print(p.age);//print(p.atk);//print(p.def);//p.name = "DamnF";//p.age = 21;//p.atk = 999;//p.def = 4444;//p.Save ();  //p.Load ();//print(p.name);//print(p.age);//print(p.atk);//print(p.def);Player p = new Player();p.Load();//装备信息print(p.items .Count );for (int i = 0; i < p.items .Count ; i++){print("道具Id"+p.items[i].id);print("道具数量"+p.items[i].num );}Item item=new Item();item.id = 1;item.num = 1;p.items .Add(item);Item item1 = new Item();item1.id = 1;item1.num = 1;p.items.Add(item1);p.Save();}// Update is called once per framevoid Update(){}
}

数据存储位置

windows

  • 位置 (Unity 2020.1 之前版本):​
    • 存储在一个 ​​注册表项​​ 中。
    • 具体路径:HKEY_CURRENT_USER\Software\[CompanyName]\[ProductName]
    • [CompanyName]:你在 Unity 项目设置 (Edit -> Project Settings -> Player -> Company Name) 或构建时设置的 "Company Name"。
    • [ProductName]:你在 Unity 项目设置 (Edit -> Project Settings -> Player -> Product Name) 或构建时设置的 "Product Name"。
  • ​位置 (Unity 2020.1 及之后版本):​
    • 出于兼容性、安全和跨平台一致性考虑,​​默认存储方式改为文件存储​​。
    • ​文件路径:​
      • %userprofile%\AppData\LocalLow\[CompanyName]\[ProductName]\
      • 文件名通常是:PlayerPrefs.txt 或基于项目标识的文件。
    • %userprofile% 是当前用户的文件夹(例如 C:\Users\YourUsername)。
    • AppData\LocalLow 文件夹是一个具有低完整性级别的特殊文件夹(适用于可能处理敏感数据的应用程序)。
  • ​如何访问:​
    • 打开文件资源管理器。
    • 在地址栏直接输入 %userprofile%\AppData\LocalLow\[CompanyName],回车。
    • 查找你的游戏项目名称文件夹,里面的文件就是 PlayerPrefs 数据。
  • ​自定义路径 (Unity 2020.1+):​
    • 如果你在首次访问 PlayerPrefs 之前调用了 PlayerPrefs.SetFilePath(string fullPath),数据将存储在 fullPath 指定的完整路径文件中(例如 C:\MyGameData\my_prefs.dat)。

Android

  • ​位置:​
    • PlayerPrefs 使用 Android 的 ​​Shared Preferences​​ 机制进行存储。
    • 存储在应用私有目录下的一个 ​​XML 文件​​ 中。
    • ​完整路径 (在设备上):​
      /data/data/[package.name]/shared_prefs/unity.[player_settings_identifier].v2.playerprefs.xml
    • [package.name]:你的 Android 应用的唯一包名(例如 com.YourCompany.YourGame)。
    • [player_settings_identifier]:基于 Player Settings 计算出的一个标识符,通常和你的游戏项目名强相关,但不直接是项目名(可以简单理解为游戏唯一标识)。
  • ​文件内容:​
    • 是一个 XML 文件,键和值(字符串形式)清晰可见。
    • .v2. 表明使用的是 Unity 的 v2 偏好设置系统(较新的稳定版本)

Ios

   位置:​

  • PlayerPrefs 使用 iOS 的 ​​User Defaults 系统​​(NSUserDefaults API)进行存储。
  • 存储在应用沙盒内一个特定的 ​​Property List (.plist) 文件​​ 中。
  • ​完整路径 (在设备上):​
    /var/mobile/Containers/Data/Application/[App-GUID]/Library/Preferences/[bundle.id].plist
  • [App-GUID]:iOS 系统为每个已安装应用随机生成的唯一目录标识符(UDID)。每次应用重新安装都会变。
  • [bundle.id]:你的应用的 Bundle Identifier (在 Unity 的 Player Settings 中设置,类似于 Android 的包名,如 com.YourCompany.YourGame)。最终文件名通常就是 [bundle.id].plist

所有平台上的存储文件​​默认都没有加密​​,内容可视可修改(易被玩家作弊)。​​绝不用 PlayerPrefs 存需要保护的核心数据!

PlayerPrefs数据的唯一性

PlayerPrefs 中不同数据的唯一性
是由 key 决定的,不同的 key 决定了不同的数据
同一项目中 如果不同数据 key 相同 会造成数据丢失
要保证数据不丢失就要建立一个保证 key 唯一性的规则

练习题--玩家游戏排行榜

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class RankInfoList
{public List<RankInfo> rankLists;public void Add(string name,int score,int time){rankLists .Add (new RankInfo (name,score,time));}public RankInfoList (){Load();}public void Save(){//设置rankLists中RankInfo的数量PlayerPrefs .SetInt ("RankInfoNum",rankLists .Count);for (int i = 0; i < rankLists.Count; i++){PlayerPrefs.SetString("rankName" + i, rankLists[i].rankName);PlayerPrefs.SetInt("rankScore" + i, rankLists[i].rankScore);PlayerPrefs.SetInt("rankTime" + i, rankLists[i].rankTime);}PlayerPrefs .Save();}private void Load(){//得到rankLists中RankInfo的数量int num = PlayerPrefs.GetInt("RankInfoNum", 0);//初始化容器rankLists = new List<RankInfo>();RankInfo rankInfo;for (int i = 0;i < num;i++){rankInfo = new RankInfo(PlayerPrefs.GetString("rankName" + i),PlayerPrefs.GetInt("rankScore" + i),PlayerPrefs.GetInt("rankTime" + i));rankLists.Add(rankInfo);}}
}
/// <summary>
/// 单条玩家排行信息
/// </summary>
public class RankInfo
{public string rankName;public int rankScore;public int rankTime;public RankInfo(string name,int score,int time){rankName = name;rankScore = score;rankTime = time;}
}
public class Lesson2 : MonoBehaviour
{// Start is called before the first frame updatevoid Start(){RankInfoList rankList=new RankInfoList();print(rankList.rankLists.Count);for (int i = 0; i < rankList .rankLists .Count ; i++){print("名字:" + rankList.rankLists[i].rankName);print("分数:" + rankList.rankLists[i].rankScore);print("时间:" + rankList.rankLists[i].rankTime);}rankList.Add("DamnF", 100, 100);rankList.Save();}// Update is called once per framevoid Update(){}
}

http://www.lryc.cn/news/597108.html

相关文章:

  • Hexo - 免费搭建个人博客06 - 安装、切换主题Butterfly
  • 基于Java实现DFT、FFT,并绘制波形图和频谱图,音频播放频谱或波形图
  • 内积(Inner Product)和余弦相似度区别
  • MATLAB近红外光谱分析:MATLAB编程+BP神经网络+SVM+随机森林+遗传算法+变量降维+卷积神经网络等
  • 以 “有机” 重构增长:云集从电商平台到健康生活社区的跃迁
  • 零工合规挑战:盖雅以智能安全体系重构企业用工风控
  • 认识linux进程内存布局以及与命令行参数和环境变量的关系
  • 如何在VS code里使用SQLtool连接上WSL上的MySQL服务
  • 【软件系统架构】系列七:物联网云平台系统性能深入解析
  • 线性神经网络(深度学习-李沐-学习笔记)
  • 探索大语言模型(LLM):提升 RAG 性能的全方位优化策略
  • 我考PostgreSQL中级专家证书二三事
  • 论文略读:REMEDY: RECIPE MERGING DYNAMICS IN LARGE VISION-LANGUAGE MODELS
  • vue3笔记(2)自用
  • 微软2025教育AI报告:教育群体采用AI的比例显著提升
  • 技术速递|使用 Semantic Kernel 与 A2A 协议构建多智能体解决方案
  • Qt 样式表(QSS):打造个性化界面
  • 【前端】【Vue DevTools】Vue DevTools 进阶:用 Trae / Cursor 替换 VSCode 打开文件(跳转行列无误)
  • 论文略读:Knowledge is a Region in Weight Space for Finetuned Language Models
  • iOS上使用WebRTC推拉流的案例
  • 想曰加密工具好用吗?本地安全、支持多算法的加密方案详解
  • ZLMediaKit流媒体服务器WebRTC页面显示:使用docker部署
  • 基于Matlab传统图像处理技术的车辆车型识别与分类方法研究
  • 【第三章自定义检视面板_创建自定义编辑器_如何创建自定义PropertyDrawer(9/9)】
  • 第六章 W55MH32 UDP Multicast示例
  • 在离线 Ubuntu 22.04机器上运行 ddkj_portainer-cn 镜像 其他相关操作也可以复刻 docker
  • CCD工业相机系统设计——基于FPGA设计
  • 【后端】FastAPI的Pydantic 模型
  • 【Linux-云原生-笔记】keepalived相关
  • 蒙牛社交电商的升级路径研究:基于开源链动2+1模式、AI智能名片与S2B2C商城小程序源码的融合创新