【图文详解】Unity存储游戏数据的几种方法

这篇具有很好参考价值的文章主要介绍了【图文详解】Unity存储游戏数据的几种方法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


在Unity中,常用的数据存储方法包括PlayerPrefs、ScriptableObject、JSON、XML和数据库等。

PlayerPrefs是Unity自带的一种简单的键值存储系统,适合存储一些简单的游戏数据。ScriptableObject是一种Unity类,可用于创建可序列化的对象并存储数据。JSON和XML是轻量级的数据交换格式,可以通过读写文件的方式进行数据存储和传输。对于存储大量数据,使用数据库则是更好的选择。

1 PlayerPrefs: Unity自带的一种简单的键值存储系统

PlayerPrefs是Unity自带的一种简单的键值(键即用于查找的关键字,值即存储的数据)存储系统,用于存储少量的游戏数据。PlayerPrefs是基于本地文件存储数据的,数据以键值对的形式保存在本地磁盘上。

PlayerPrefs主要适用于一些简单的游戏数据的存储,例如玩家的音效、音乐、难度等级等。使用PlayerPrefs可以方便地在游戏中读写这些数据。

PlayerPrefs的使用非常简单。首先需要使用
PlayerPrefs.SetInt()、
PlayerPrefs.SetFloat()、
PlayerPrefs.SetString()等方法将数据存储在PlayerPrefs中。
例如,用PlayerPrefs.SetInt(“Level”, 5)将当前玩家的游戏等级存储在PlayerPrefs中。然后在需要使用这些数据的地方,使用PlayerPrefs.GetInt()、PlayerPrefs.GetFloat()、PlayerPrefs.GetString()等方法从PlayerPrefs中读取数据。

具体例子就不多讲了,网上有很多介绍。但需要注意的是,PlayerPrefs只适合存储少量数据,如果需要存储大量数据,建议使用其他的数据存储方式,如ScriptableObject、JSON、XML或数据库等。此外,PlayerPrefs存储的数据可以被修改或删除,因此在实际开发中需要注意数据安全性和数据的备份。

2 ScriptableObject: Unity中最灵活的数据管理工具

ScriptableObject是Unity中的一个类,可以用于创建可序列化的对象并存储数据。它们的序列化和反序列化速度更快,消耗的内存更少。与常规的游戏对象不同,ScriptableObject不依赖于场景,也不需要被实例化,因此可以独立于游戏对象存在。

使用ScriptableObject可以方便地创建自定义的数据类,存储一些游戏数据,例如角色属性、游戏设置、关卡数据等。这些数据可以在不同场景之间共享,也可以在不同的游戏对象之间共享。

创建ScriptableObject非常简单。首先,需要在Unity编辑器中创建一个ScriptableObject类,该类需要继承自ScriptableObject,并添加[CreateAssetMenu]属性。然后,需要实现需要存储的数据成员,并将其声明为public或[SerializeField],使其可以被序列化并存储在ScriptableObject中。

下面开始演示:
首先,在Unity编辑器中,创建一个名为MyData的ScriptableObject类:

using UnityEngine;
//关于[CreateAssetMenu]下面有介绍
[CreateAssetMenu(fileName = "NewData", menuName = "MyData", order = 51)]
public class MyData : ScriptableObject
{//
    public int level;
    public float health;
    public string playerName;
}

这里我们定义了一个包含level、health和playerName三个属性的MyData类。属性的类型可以是任何Unity支持的类型,包括int、float、string、Vector3等。

在本例中,我们将数据存储在ScriptableObject对象中,并在控制台中输出这些数据:

public class DataManager : MonoBehaviour
{
    public MyData data;

    void Start()
    {
        // 将数据存储在ScriptableObject对象中
        data.level = 10;
        data.health = 80.0f;
        data.playerName = "XiaoMing";

        // 从ScriptableObject对象中读取数据并输出到控制台
        Debug.Log("Level: " + data.level);
        Debug.Log("Health: " + data.health);
        Debug.Log("Player Name: " + data.playerName);
    }
}

在这段代码中,我们首先在Start()函数中将数据存储在ScriptableObject对象中。然后,通过访问ScriptableObject对象中的属性来读取这些数据,并将其输出到控制台中。

在第一段代码中的[CreateAssetMenu]是一个特性(Attribute),用于在Unity编辑器中为ScriptableObject类创建一个自定义的上下文菜单,方便用户在Project窗口中创建和管理ScriptableObject对象。该特性包含三个参数:

  1. fileName:表示创建的ScriptableObject对象的文件名。在这里,我们使用"NewData"作为文件名。
  2. menuName:表示在Unity编辑器中创建菜单项的路径,以“/”作为分隔符。在这里,我们使用"MyData"作为菜单名,并将其放在根目录下。
  3. order:表示菜单项在上下文菜单中的排序位置。较小的数字表示菜单项靠前。在这里,我们用51作为排序位置。

当我们在Unity编辑器中右键单击Project窗口中的文件夹时,会看到一个名为"MyData"的菜单项。点击它,就可以在该文件夹下创建一个新的ScriptableObject对象,并自动命名为"NewData"。

使用[CreateAssetMenu]特性可以大大简化ScriptableObject对象的创建过程,并使用户更容易使用和管理这些对象。

2.1 如何手动创建和修改数据文件

如果要手动创建和编辑数据文件,那么可以使用AssetDatabase.CreateAsset()方法,它只能在Unity编辑器中使用,不能在游戏运行时使用。使用该方法,开发人员可以方便地创建、修改和管理ScriptableObject对象,提高开发效率并简化资源管理。

这是一个使用AssetDatabase.CreateAsset()方法创建ScriptableObject对象的示例:

using UnityEngine;
using UnityEditor;

public class CreateData : MonoBehaviour
{
    [MenuItem("Tools/Create Data")]
    static void CreateMyData()
    {
        // 创建一个新的MyData对象,MyData是上放刚刚创建的MyData类
        MyData data = ScriptableObject.CreateInstance<MyData>();

        // 设置MyData对象的属性
        data.level = 10;
        data.health = 80.0f;
        data.playerName = "Tom";

        // 在Assets文件夹中创建一个名为"MyData.asset"的新文件,并将MyData对象保存到该文件中
        AssetDatabase.CreateAsset(data, "Assets/MyData.asset");
        AssetDatabase.SaveAssets();

        // 在控制台输出创建的MyData对象的信息
        Debug.Log("Created MyData asset: " + AssetDatabase.GetAssetPath(data));
        Debug.Log("Level: " + data.level);
        Debug.Log("Health: " + data.health);
        Debug.Log("Player Name: " + data.playerName);
         // 也可以刷新Asset数据库,这样在编辑器中看到新创建的Asset
        AssetDatabase.Refresh();
    }
}

2.2 ScriptableObject优缺点总结

ScriptableObject的优点在于可以方便地创建自定义的数据类,可以在不同的场景或游戏对象之间进行传递、共享数据,还可以使用版本控制工具管理数据的修改。与PlayerPrefs相比,ScriptableObject可以存储大量的游戏数据,且更加灵活和安全。

但是,使用ScriptableObject也有一些限制。例如,由于ScriptableObject不依赖于场景,因此不能直接使用场景中的游戏对象。此外,ScriptableObject存储的数据是以.asset文件的形式保存在本地磁盘上的,因此需要注意数据的安全性和备份。

3 JSON: 轻量级的数据交换格式

3.1 序列化与反序列化

在讲本篇内容之前,首先我们要知道什么是“序列化”和“反序列化”。
序列化是将对象转换为可传输或可存储的格式的过程。序列化可以将一个对象转换为二进制数据流、XML文档或JSON字符串等格式。
反序列化是将序列化的数据转换回对象的过程。反序列化可以将二进制数据流、XML文档或JSON字符串等格式的数据转换回原始的对象,以便在程序中继续使用这些数据。例如,在Unity游戏中,可以从服务器或其他客户端接收JSON格式的字符串,并将其反序列化为游戏数据对象。
【图文详解】Unity存储游戏数据的几种方法
JSON和XML是常用的文本格式,它们都支持跨平台传输,并且易于阅读和处理。在Unity中,可以使用XmlSerializer类或JsonUtility类将对象序列化为相应的XML或JSON格式的字符串,然后通过网络传输。

二进制格式可以更有效地传输数据,因为它可以减少数据量和传输时间。在Unity中,可以使用BinaryFormatter类将对象序列化为二进制格式的字节数组,然后通过网络传输。但需要注意的是,二进制格式不太易读和处理,因此在开发和调试阶段,使用文本格式可以更方便。

在实际的开发中,开发人员通常会根据具体的应用场景选择不同的数据传输格式。例如,如果数据需要在Web应用程序之间传输,则JSON格式通常是首选,因为它比XML格式更轻量级。如果数据需要与其他系统进行交互,则XML格式通常是首选,因为它是一种通用的数据交换格式,被广泛使用。
下表总结了JSON、XML和二进制数据的特点和使用场景:

数据格式 特性 使用场景
JSON 轻量级、易读、易解析、支持复杂数据类型、支持嵌套数据结构 Web应用程序、移动应用程序、API交互、跨平台应用程序
XML 通用的数据交换格式、可扩展性好。支持复杂数据类型、支持嵌套数据结构、支持命名空间 数据交换、Web服务、中间件、跨平台应用程序
二进制 传输效率高、数据量小、可扩展、支持复杂数据类型、安全性高 游戏开发、高性能应用程序、大规模数据处理、机器学习

3.2 用JsonUtility对对象进行序列化和反序列化

在Unity中,可以使用JsonUtility、XMLSerializer、BinaryFormatter等工具对对象进行序列化和反序列化。

下面是一个示例代码,演示如何使用JsonUtility类将一个包含多个属性的对象序列化为JSON格式的字符串,以及如何将JSON格式的字符串反序列化为对象。

using UnityEngine;
using System;

// 定义一个包含多个属性的类
[Serializable]
public class PlayerData
{
    public int level;
    public string playerName;
    public float health;
}

public class JsonDemo : MonoBehaviour
{
    void Start()
    {
        // 创建一个PlayerData对象并设置属性
        PlayerData player = new PlayerData();
        player.level = 10;
        player.playerName = "XiaoMing";
        player.health = 100.0f;

        // 将PlayerData对象序列化为JSON格式的字符串
        string json = JsonUtility.ToJson(player);

        // 打印序列化后的JSON字符串
        Debug.Log("JSON: " + json);

        // 将JSON字符串反序列化为PlayerData对象
        PlayerData player2 = JsonUtility.FromJson<PlayerData>(json);

        // 打印反序列化后的对象的属性
        Debug.Log("Level: " + player2.level);
        Debug.Log("Name: " + player2.playerName);
        Debug.Log("Health: " + player2.health);
    }
}

在代码中,首先定义了一个包含多个属性的PlayerData类,并使用[Serializable]属性将其标记为可序列化。然后,在Start()方法中,创建了一个PlayerData对象,并将其序列化为JSON格式的字符串,使用JsonUtility.ToJson()方法实现。接着,打印序列化后的JSON字符串。然后,使用JsonUtility.FromJson()方法将JSON格式的字符串反序列化为PlayerData对象,并打印反序列化后的对象的属性

需要注意的是,JsonUtility类只能序列化和反序列化Unity支持的类型,例如int、float、string、Vector3等。如果需要序列化其他类型的对象,需要自己实现序列化和反序列化的逻辑。此外要注意JSON格式的字符串的安全性和数据完整性。

4 XML:一种可扩展标记语言

XML(Extensible Markup Language)是一种可扩展标记语言。在Unity中,可以使用XmlSerializer类将对象序列化为XML格式的字符串,也可以将XML格式的字符串反序列化为对象。

下面是一个示例代码,演示了如何将一个包含多个属性的对象序列化为XML格式的字符串,以及如何将XML格式的字符串反序列化为对象。

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Xml.Serialization;
using System.IO;

// 定义一个包含多个属性的类
[XmlRoot("PlayerData")]
public class PlayerData
{
    [XmlElement("Level")]
    public int level;

    [XmlElement("PlayerName")]
    public string playerName;

    [XmlElement("Health")]
    public float health;
}

public class XmlDemo : MonoBehaviour
{
    void Start()
    {
        // 创建一个PlayerData对象并设置属性
        PlayerData player = new PlayerData();
        player.level = 10;
        player.playerName = "XiaoMing";
        player.health = 100.0f;

        // 将PlayerData对象序列化为XML格式的字符串
        XmlSerializer serializer = new XmlSerializer(typeof(PlayerData));
        StringWriter writer = new StringWriter();
        serializer.Serialize(writer, player);
        string xml = writer.ToString();

        // 打印序列化后的XML字符串
        Debug.Log("XML: " + xml);

        // 将XML字符串反序列化为PlayerData对象
        StringReader reader = new StringReader(xml);
        PlayerData player2 = serializer.Deserialize(reader) as PlayerData;

        // 打印反序列化后的对象的属性
        Debug.Log("Level: " + player2.level);
        Debug.Log("Name: " + player2.playerName);
        Debug.Log("Health: " + player2.health);
    }
}

在代码中,首先定义了一个包含多个属性的PlayerData类,并使用[XmlRoot]和[XmlElement]属性将其标记为可序列化。然后,在Start()方法中,创建了一个PlayerData对象,并将其序列化为XML格式的字符串,使用XmlSerializer类实现。接着,打印序列化后的XML字符串。然后,使用XmlSerializer.Deserialize()方法将XML格式的字符串反序列化为PlayerData对象,并打印反序列化后的对象的属性。

需要注意的是,XmlSerializer类只能序列化和反序列化具有公共无参数构造函数的对象。此外,需要注意XML格式的字符串的安全性和数据完整性。

5 三者特点总结

CSDN的表不太好做,直接截图吧:
【图文详解】Unity存储游戏数据的几种方法

这只是一份简单的总结,实际上在选择数据格式时,还需要考虑许多其他因素,如开发成本、可维护性、兼容性等。

6 数据库:存储大量数据时使用的一种方法

数据库一般用于存储大量的结构化数据。在游戏中,我们通常需要存储大量的数据,比如玩家的角色信息、物品信息等,这时候使用数据库就非常合适。本文将介绍如何在Unity中使用SQLite数据库来存储游戏数据。

1.安装SQLite插件

使用SQLite数据库需要安装插件。

2.创建数据库和表

可以使用SQLiteConnection类来连接SQLite数据库:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Mono.Data.Sqlite;

public class DatabaseManager : MonoBehaviour
{
    private string connectionString;

    // Start is called before the first frame update
    void Start()
    {
        connectionString = "URI=file:" + Application.dataPath + "/PlayerData.db";
        CreateTable();
    }

    // 创建表
    void CreateTable()
    {
        using (var conn = new SqliteConnection(connectionString))
        {
            conn.Open();

            using (var cmd = conn.CreateCommand())
            {
                cmd.CommandText = "CREATE TABLE IF NOT EXISTS Player (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, level INTEGER)";
                cmd.ExecuteNonQuery();
            }
        }
    }
}

上述代码中,我们首先定义了一个名为connectionString的字符串变量,用于存储连接字符串。在Start函数中,我们将connectionString设置为数据库文件的路径。

然后,我们在CreateTable函数中创建了一个名为"Player"的表,其中包含三个字段:id、name和level。id字段是主键,使用AUTOINCREMENT关键字表示自动递增。name字段存储角色的名称,level字段存储角色的等级。注意使用IF NOT EXISTS语句来判断表是否已经存在,避免重复创建。

3.插入和查询数据

创建了数据库和表之后,就可以向表中插入数据和查询数据了。以下是一个示例代码,演示如何向"Player"表中插入一条玩家角色信息,并查询所有的角色信息。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Mono.Data.Sqlite;

public class DatabaseManager : MonoBehaviour
{
    private string connectionString;

    // Start is called before the first frame update
    void Start()
    {
        connectionString = "URI=file:" + Application.dataPath + "/PlayerData.db";
        CreateTable();//创建表
        InsertData("Jack", 10);//向"Player"表中插入一条玩家角色信息
        QueryData();//查询所有的角色信息
    }

    // 创建表
    void CreateTable()
    {
        using (var conn = new SqliteConnection(connectionString))
        {
            conn.Open();

            using (var cmd = conn.CreateCommand())
            {
                cmd.CommandText = "CREATE TABLE IF NOT EXISTS Player (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, level INTEGER)";
                cmd.ExecuteNonQuery();
            }
        }
    }

    // 插入数据
    void InsertData(string name, int level)
    {
        using (var conn = new SqliteConnection(connectionString))
        {
            conn.Open();

            using (var cmd = conn.CreateCommand())
            {
                cmd.CommandText = "INSERT INTO Player (name, level) VALUES (@name, @level)";
                cmd.Parameters.AddWithValue("@name", name);
                cmd.Parameters.AddWithValue("@level", level);
                cmd.ExecuteNonQuery();
            }
        }
    }

    // 查询数据
    void QueryData()
    {
        using (var conn = new SqliteConnection(connectionString))
        {
            conn.Open();

            using (var cmd = conn.CreateCommand())
            {
                cmd.CommandText = "SELECT * FROM Player";

                using (var reader = cmd.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        var id = reader.GetInt32(0);
                        var name = reader.GetString(1);
                        var level = reader.GetInt32(2);

                        Debug.LogFormat("id: {0}, name: {1}, level: {2}", id, name, level);
                    }
                }
            }
        }
    }
}

上述代码中,我们首先在Start函数中调用CreateTable函数来创建表。然后,我们调用InsertData函数来向"Player"表中插入一条玩家角色信息。在InsertData函数中,我们使用INSERT INTO语句来插入数据,使用@name和@level占位符来设置参数的值。

在QueryData函数中,我们使用SELECT语句来查询数据,并使用reader对象来读取查询结果。注意,我们使用GetInt32和GetString方法来读取不同类型的字段值。

这就是使用SQLite数据库在Unity中存储游戏数据的方法,通过这种方法,我们可以轻松地存储大量的结构化数据,方便地进行数据的插入、查询、更新和删除等操作。

结束语

总的来说,在游戏开发中,存储游戏数据是非常重要的,因为游戏数据决定了游戏的各个方面,例如游戏的进度、玩家的成就、游戏的设置等等

不同的方法有不同的特点和应用场景,在实际的游戏开发中,我们可以根据实际的需求选择合适的数据存储方法。如果我们只存储一些简单的数据,可以选择PlayerPrefs;如果存储一些复杂的数据,可以选择JSON或XML;如果需要存储大量的结构化数据,可以选择SQLite数据库。掌握这些存储数据的技巧将有助于我们更好地开发游戏并提供更好的用户体验。文章来源地址https://www.toymoban.com/news/detail-403843.html

到了这里,关于【图文详解】Unity存储游戏数据的几种方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Unity 之 转微信小游戏本地数据存储方法分享

    近期在将Unity转换为小游戏的时候发现在读写本地文件的时候,使用 Application.persistentDataPath 缓存路径来保存文件失败,原因是WebGL的平台限制。所以导致了原有读写本地文件的代码需要根据平台进行修改。 一种最简单的方式就是将原来存储到文件中的内容,在WebGL平台使用

    2024年02月05日
    浏览(64)
  • Unity 之 抖音小游戏本地数据最新存储方法分享

    抖音小游戏是一种基于抖音平台开发的小型游戏,与传统的 APP 不同,抖音小游戏运行在抖音客户端内部,可以通过抖音的分享、推荐等功能进行传播。在抖音小游戏开发过程中,文件存储系统是一个非常重要的组成部分,本文将详细介绍抖音小游戏文件存储系统的实现原理

    2024年02月11日
    浏览(55)
  • Unity读取Json的几种方法

    目录 存入和读取JSON工具 读取本地Json文件 1、unity自带方法 类名:JsonUtility          序列化:ToJson()                    反序列化:FromJson()         用于接收的JSON实体类需要声明 [Serializable]  序列化 实体类中的成员变量要是字段而不是属性{get;set;} 处理数组的话,外

    2024年01月21日
    浏览(43)
  • Unity——延时执行的几种方法

    延时执行的函数,可以自己设定延时要执行的函数和具体延时的时间,是Monobehaviour基类中实现好的方法 在Update等刷新函数内计时,timer += Time.deltaTime 当时间达到预期,执行需要延时的方法。需要注意的是,增量时间Time.deltaTime是每帧都不同的浮点数。计时器不能用 == 去判断

    2024年02月11日
    浏览(38)
  • Python爬虫数据存哪里|数据存储到文件的几种方式

    前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 爬虫请求解析后的数据,需要保存下来,才能进行下一步的处理,一般保存数据的方式有如下几种: 文件:txt、csv、excel、json等,保存数据量小。 关系型数据库:mysql、oracle等,保存数据量大。 非关系型数据库:Mongodb、R

    2024年02月09日
    浏览(52)
  • unity碰撞检测识别对象的几种方法,刚体篇

    可以在物体的Collider组件中设置碰撞层级,只有属于指定层级的物体才会响应碰撞事件。例如,我们可以将敌人设置为一个单独的层级,然后在玩家的脚本中检测碰撞时,只响应属于敌人层级的物体。 可以在物体的Collider组件中设置标签,然后在脚本中检测碰撞时,只响应标

    2024年02月11日
    浏览(38)
  • 【unity】关于unity3D摄像机视角移动的几种方式详解

    目录 一、前言 二、Transform基础 1、几种坐标系 2、position和localPosition属性 3、rotation属性 三、摄像机的平移 1、键盘控制平移 2、鼠标控制平移 3、整合  四、摄像机的旋转 1、绕自身旋转 2、绕目标物体旋转 3、整合  五、优化功能 1、调整速率 2、切换目标物体 3、设置常用摄

    2024年02月04日
    浏览(41)
  • 手机切换ip地址的几种方法详解

    在某些情况下,我们可能需要切换手机的IP地址来实现一些特定的需求,如解决某些应用程序的限制、绕过IP封禁等。本文将为大家分享几种切换手机IP地址的方法,让您能够轻松应对各种需求。 一、使用动态服务器 使用动态服务器是一种常见的切换手机IP地址的方法。动态服

    2024年02月07日
    浏览(50)
  • 【笔记】Unity2D角色和物体移动的几种方法

    在Unity中对于物体移动有多种方法,这里根据b站up主【鼓励Jun】的视频整理了一些笔记 变量声明: 位移向量var dir=new Vector3(deltax.deltay,deltaz); 移动速度var speed=2; ps:变量声明都在主要都在方法外,实际位移操作则在Update方法中。 #键盘输入,这里举一个只x轴上移动的例子,y轴同

    2023年04月08日
    浏览(58)
  • 求最大公约数的几种常见的方法 【详解】

    目录 一、关于公约数 二、计算最大公约数的方法  1. 辗转相除法(欧几里得算法) 2. 更相减损法(辗转相减法) 3. 分解质因数法 4. 穷举法  5. 递归法 6. 短除法 三、总结 首先 ,先介绍一下公约数: 公约数(公因数),一个能被若干个整数同时整除的的整数,公约数中最大

    2024年02月08日
    浏览(60)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包