Unity中游戏数据存储

本文介绍了Unity中游戏数据的两种主要存储方式:本地存储(如PlayerPrefs、ScriptableObject和SQLite)以及网络存储(服务器端数据库)。详细解释了如何使用PlayerPrefs进行玩家偏好数据存储,并展示了ScriptableObject作为数据容器的应用示例。
摘要由CSDN通过智能技术生成

Unity中游戏数据存储

  • 简介

游戏数据存储的方法很多,分本地和网络存储,本地存储有txt文件、json、PlayerPrefs、ScriptableObject和SQLite数据库读写等等;网络存储则是数据存储在服务器端,然后通过网络传输的方式进行存储。

  • 本地存储

1)PlayerPrefs玩家偏好数据存储

PlayerPrefs是一个在游戏会话之间存储玩家偏好的类。它可以将字符串、浮点值和整数值存储到用户的平台注册表中。Unity将PlayerPrefs存储在本地注册表中,无需加密。请勿使用PlayerPrefs数据存储敏感数据。

它的基本方法如下:

DeleteAll

从首选项中删除所有键和值。

DeleteKey

从PlayerPrefs中删除给定的密钥。如果密钥不存在,DeleteKey就没有影响。

GetFloat

返回与首选项文件中的键(如果存在)相对应的值。

GetInt

返回与首选项文件中的键(如果存在)相对应的值。

GetString

返回与首选项文件中的键(如果存在)相对应的值。

HasKey

如果给定密钥存在于PlayerPrefs中,则返回true,否则返回false。

Save

保存所有修改的首选项。

SetFloat

设置由给定键标识的首选项的浮点值。您可以使用PlayerPrefs。GetFloat以检索此值。

SetInt

为给定键标识的首选项设置一个整数值。您可以使用PlayerPrefs。GetInt可以检索此值。

SetString

为给定键标识的首选项设置单个字符串值。您可以使用PlayerPrefs。GetString以检索此值。

例子讲解

下面的代码截取自我自己的个人游戏项目,功能为保存玩家的所有用户的数据

public void SavePlayerData()

        {

//EduGlobalData.CONST_PlayerNum为玩家的角色的数量(玩家可以建立多个角色)

            for (int i = 0; i < EduGlobalData.CONST_PlayerNum; ++i)

            {

                string str = EduGlobalData.CONST_PlayerNumDesc + i;

                //将玩家的所有角色的数据存储到PlayerPrefs里,如名字、头像的名称、性别、职业、等级、当前经验值等等

                Player pl = GetPlayerFromID(i);

                if (pl != null)

                {

                    PlayerPrefs.SetInt(str, i);

                    PlayerPrefs.SetString(str + "name", pl.name);

                    PlayerPrefs.SetString(str + "headPic", pl.headPic);

                    PlayerPrefs.SetInt(str + "IsBoy", (int)pl.isBoy);

                    PlayerPrefs.SetInt(str + "carrer", (int)pl.carrer);

                    PlayerPrefs.SetInt(str + "level", (int)pl.level);

                    PlayerPrefs.SetInt(str + "exp", (int)pl.exp);

                }

                else

                {

                    PlayerPrefs.SetInt(str, -1);

                }

            }

        }

下面的代码是从使用PlayerPrefs读取出玩家的所有角色的数据,如名字、头像的名称、性别、职业、等级、当前经验值等等

            for (int i = 0; i < EduGlobalData.CONST_PlayerNum; ++i)

            {

                string str = EduGlobalData.CONST_PlayerNumDesc + i;

                int playerId = PlayerPrefs.GetInt(str, -1);

                if (playerId == -1)

                    continue;

                Player pl = new Player();

                pl.id = playerId;

                pl.name = PlayerPrefs.GetString(str + "name");

                pl.headPic = PlayerPrefs.GetString(str + "headPic");

                pl.isBoy = PlayerPrefs.GetInt(str + "IsBoy");

                pl.carrer = PlayerPrefs.GetInt(str + "carrer");

                pl.level = PlayerPrefs.GetInt(str + "level");

                pl.exp = PlayerPrefs.GetInt(str + "exp");

                

                int maxExp = 0;

                int maxHp = 0;

                int maxMp = 0;

                GetPlayerDataFromLevel(pl.level, ref maxExp, ref maxHp, ref maxMp);

                pl.maxExp = maxExp;

                pl.hp = pl.maxHp = maxHp;

                pl.mp = pl.maxMp = maxMp;

                UserData.PlayerList.Add(pl);

           }

  1. 从应用外部读取,适合发布应用后需要在后期随时修改

//从与工程的同级目录Assets下读取DataFile.txt文件

string dPath = Application.dataPath;

        int num = dPath.LastIndexOf("/");

        dPath = dPath.Substring(0, num);

        string url = dPath + "/DataFile.txt";

        strs = File.ReadAllLines(url);

//将数据逐行读取出来,然后存入到自己建立的数据结构中

        for (int i = 0; i < 6; ++i)

        {

            SpeedRangeToMove.Add(new SpeedRangeStruct());

            string str = strs[i];

            string[] data = str.Split(',');//每行的内容以,分割,所以需要这样做

            //将数据转换成我们需要的类型,如int、float等等

            SpeedRangeToMove[i].MoveBegin = int.Parse(data[0]);

            SpeedRangeToMove[i].MoveEnd = int.Parse(data[1]);

            SpeedRangeToMove[i].AniSpeed = float.Parse(data[2]);

            SpeedRangeToMove[i].VideoSpeed = float.Parse(data[3]);

        }

DataFile.txt内的数据内容为

0,4,0.12,0.8

4,6,0.17,0.9

6,8,0.21,1.1

8,12,0.3,1.3

12,16,0.39,1.5

16,30,0.48,1.7

4

记住当应用发布后将DataFile.txt文件拷贝到exe文件的同级目录下

3)使用Resources.Load从应用内读取数据

Resources类的函数成员 public static T Load(string path); 用于加载存储在资源文件夹中”path”路径处的指定类型的数据资源

这是项目中的一部分代码

        TextAsset ta = Resources.Load("kbData/d_xbAvatar_inittab.py.datas") as TextAsset;

        //将资源转化成JsonData对象

        JsonData jd = JsonMapper.ToObject(ta.text);

        

        //按数据的格式进行解析,并存储到自定义的数据结构中

        foreach (var key in jd.Keys)

        {

            PlayerGameData.Instance.Avatar_inittabs.Add(UInt16.Parse(key.ToString()),

                new Avatar_inittab(UInt16.Parse(key.ToString()), UInt64.Parse(jd[key]["exp"].ToString()),

                UInt16.Parse(jd[key]["room_level"].ToString()),

                UInt16.Parse(jd[key]["world_level"].ToString())));

        }

代码示例为加载项目工程的“Resources”目录下"kbData/d_xbAvatar_inittab.py.datas"文件,文件是json格式,所以可以使用litjson进行解析

4)ScriptableObject数据容器

简介

ScriptableObject是一个可独立于类实例来保存大量数据的数据容器。如果你想创建独立于GameObjects的对象,你可以从中派生一个类。

常用的api

Static Methods

CreateInstance

创建可ScriptableObject对象的实例。

Messages

Awake

当ScriptableObject脚本启动时,会调用此函数。

OnDestroy

ScriptableObject对象将被销毁时,会调用此函数。

OnDisable

当ScriptableObject对象超出范围时调用此函数。

OnEnable

加载对象时会调用此函数。

OnValidate

当加载脚本或Inspector中的值发生更改时,Unity调用的仅编辑器函数。

Reset

重置为默认值。

示例演示
(1)首先建立一个派生于ScriptableObject的脚本

using System;

using System.Collections.Generic;

using UnityEngine;

[CreateAssetMenu]

public class AddressableCreateGroup : ScriptableObject

{

    [Serializable]

    public class CreateGroupPath

    {

        [ContextMenuItem("GroupName", "Test")]

        public string GroupName;

        public string GroupPath;

        void Test() { }

    }

    [SerializeField]

    public List<CreateGroupPath> createGroupPaths = new List<CreateGroupPath>();

}

脚本中声明了我们要存储的数据的数据格式

(2)生成同名的资源文件 - 后缀名为asset

然后执行菜单命令Assets -> Create -> AddressableCreateGroup,则会生成如下同名的后缀名为“.asset”的资源文件

在属性Inspector面版中添写我们要使用到的数据

  1. 在程序中读取asset资源文件

程序中读取“.asset”资源的代码脚本内容为

//“.asset”资源的文件路径

string path = "Data/AddressableCreateGroup";

加载“.asset”资源到脚本对象“createGroup

AddressableCreateGroup createGroup = Resources.Load<AddressableCreateGroup>(path);

从脚本对象中读取资源内容

        for (int i = 0; i < createGroup.createGroupPaths.Count; i++)

        {

            ResetGroup<GameObject>(createGroup.createGroupPaths[i].GroupName, createGroup.createGroupPaths[i].GroupPath,

                                   "t:prefab", assetPath =>

            {

                string fileName = Path.GetFileNameWithoutExtension(assetPath);

                string dirPath = Path.GetDirectoryName(assetPath);

                string dirName = Path.GetFileNameWithoutExtension(dirPath);

                return $"{dirName}/{fileName}";

            });

        }

  • 服务器端数据库存储

由于篇幅有限,只能大概说下过程

大网络游戏中有游戏服务器端的,重要的数据都会存储在服务器端的数据库中如MySQL、Oracle等等。

在网络游戏中,存储和传输数据非常重要。存储主要是指将数据保存在游戏服务器或本地电脑中,而传输则是指将数据从服务器传输到玩家的电脑中,在存储方面,网络游戏通常采用数据库进行数据的存储。由于数据库具有快速、安全、可靠的特点,因此是网络游戏最常用的数据存储方式。在数据库中,数据可以被高效地管理,修改和查询。

在传输方面,网络游戏采用的是基于TCP/P协议的网络传输。这种传输方式可以保证数据的稳定传输,并且可以将数据分包传输,提高数据传输的效率

Unity游戏,可以使用JSON格式进行数据存储。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,通过简单的键值对来表示数据。可以使用LitJson.dll插件来实现在Unity读取和存储JSON数据。 以下是使用JSON进行数据存储的步骤: 1. 创建一个技能类(Skill),在该类封装需要存储的字段,比如Id和Name。 2. 创建Skill类型的List集合,并向其添加Skill对象。 3. 使用LitJson的JsonMapper.ToJson()方法将List集合转换为JSON格式的字符串。 4. 使用File.WriteAllText()方法将JSON字符串写入文件。 5. 为了防止文乱码,可以使用Regex.Replace()方法将转义字符转码为实际字符。 在Unity使用LitJson.dll插件来读取和存储JSON数据需要将LitJson.dll文件放入Unity的Plugins文件夹。编写相应的代码来实现读取和存储的功能。可以参考相关的教程或视频来学习更详细的使用方法。 <span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Unity Json读取存储](https://download.csdn.net/download/qq_42126516/12251667)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [Unity之JSON(数据存储)](https://blog.csdn.net/m0_74427422/article/details/129540637)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [学习记录:unity的json存储](https://blog.csdn.net/shijinlinaaa/article/details/125896790)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值