在Unity游戏中保存数据的最佳方式是什么?

20

我在想... 在Unity游戏中保存数据的最佳方式是什么?使用JSON吗?如果是,如何操作?感谢


https://docs.unity3d.com/Manual/JSONSerialization.html - Vapid
https://docs.unity3d.com/ScriptReference/PlayerPrefs.html(参见 https://youtu.be/gM73B5PyGh8 获取帮助),https://docs.mongodb.com/realm/sdk/dotnet/unity/(参见https://youtu.be/8jo_S02HLkI)等等 :) - Dominic Frei
3个回答

46
以下是一些在Unity项目中保存数据的不同方法:
  1. 平台无关: 在Unity3D中,一种将数据以平台无关的方式保存的方法是使用 PlayerPrefs 类。PlayerPrefs是一个静态类,很容易使用但不可靠

  2. 持久化-保存和加载数据使用 DontDestroyOnLoadPlayerPrefs和数据 序列化。 可以参考unity官方的视频教程

  3. 服务器端: 也可以使用服务器来保存数据(例如PHP和MySQL数据库的组合)。可以用它来保存得分数据,用户资料,库存等等,更多信息请参见Unity Wiki。还可以使用第三方解决方案如Firebase等。

  4. 为了将游戏内数据以后能读取的格式保存到硬盘驱动器,可以使用.NET/Mono特性中称为序列化的功能。了解更多

  5. 可以在Unity Wiki上找到有关Unity的简单JSON指南,也可以参考官方文档中的JSON序列化

  • SQLite (集成式数据库,适用于应用软件) 是获得免费套餐的另一个绝佳选择,如果您了解SQL语言,它就非常简单易用(也是我的最爱)。

  • Scriptable Object: 它是一个数据容器,用于存储不变数据。适用于大量不变数据和极大地减少项目的内存使用。

  • enter image description here

    以上内容摘自我在博客中关于Unity3D应用程序数据保存技术的文章


    假设我有几个事件一个接一个地进行,这些事件将不时通过Web服务器进行更新,并且为了保存所有事件数据在设备中,我应该使用什么?在序列化中保存所有事件数据并稍后更新数据是否可行?我所看到的只有保存和加载,而在序列化教程中没有编辑或更新。它会清除旧数据以保存新数据吗? - Zoedia
    很棒的答案,只是有点遗憾看到排名第一的是玩家偏好设置,这会导致人们将数据保存在不安全的地方。但无论如何,答案非常清晰。 - Jeroen De Clercq
    @JeroenDeClercq #1是在Unity应用程序中保存数据最简单的方法。我不知道它是否安全。 - Muhammad Faizan Khan
    PlayerPrefs 旨在存储用户的偏好设置(因此得名),例如声音音量等,不应用于存储重要数据,如游戏进度,因为它们可能会在更新应用程序时被删除! - derHugo
    但是您可以自行保存加密文本。 - Muhammad Faizan Khan
    显示剩余5条评论

    6

    您可以在资源商店中使用许多免费和付费的资产。

    免费保存游戏 - 可以进行XML和JSON格式的保存和加载。

    语法:

    Saver.Save<T> (T data, string fileName);
    

    例子:

    Saver.Save<MyData> (myData, "myData"); // The .json extension will be added automatically
    

    Save Game Pro - 二进制保存和加载。快速且安全。易于使用。

    语法:

    SaveGame.Save<T> (T data, string identifier);
    

    例子:

    SaveGame.Save<int> (score, "score");
    

    1
    如果您想将数据存储在服务器上,可以使用PHP和MySQL轻松实现。您需要执行以下步骤: 第一步:
    从服务器获取您所需的任何数据,只需使用单个字符串(下面是代码):
    <?php
    
    //SERVER CONNECTION 
    $server_name = "localhost";
    $server_user = "Er.Ellison";
    $server_pass = "supersecretPassword";
    $server_db   = "game_test_db";
    
    $connection = new mysqli($server_name , $server_user , $server_pass , $server_db);
    if(!$connection) {
      die("Connection failed !" . mysqli_connect_error());
    }
    
    // QUERY
    $query = "SELECT * FROM items";
    $result = mysqli_query($connection , $query);
    
    if(mysqli_num_rows($result) > 0){
      while($row = mysqli_fetch_array($result)){
        echo "id:" . $row['id'] . "|username:" . $row['username'] . "|type:" . $row['type'] . "|score:" . $row['score'] . ";";
      }
    } 
    ?>
    

    请注意,您必须使用分号或其他您熟悉的字符来分隔任何想要的字符串,并记住我们将在Unity中使用它。
    第二步: 现在您应该像这样从Web获取数据(它将是一个长字符串):

    enter image description here

    步骤三:
    现在进入Unity并创建一个C#脚本,将其附加到场景中的任何对象上,并打开该脚本,然后使用以下代码来操作从数据库检索到的数据:

    public class DataLoader : MonoBehaviour {
    
    
    public string[] items;
    
    
    // Use this for initialization
    IEnumerator Start () {
        WWW itemsData = new WWW ("http://localhost/_game/test/itemsdata.php");  
        yield return itemsData;
        string itemsDataStrign = itemsData.text;
        print (itemsDataStrign);
        items = itemsDataStrign.Split (';');
        print (GetDataValue(items[0] , "cost:"));
    }
    
    string GetDataValue(string data, string index) {
        string value = data.Substring (data.IndexOf(index) + index.Length);
        if (value.Contains ("|")) {
            value = value.Remove (value.IndexOf("|"));
        }
        return value; 
    }
    
    }
    

    步骤4:
    您刚刚从数据库检索了数据,请在Unity控制台中检查图像:

    enter image description here

    我为那些和我一样陷入数据库问题的人而制作了这个!

    我认为你代码中的 $reuslt(三个实例)是一个打字错误。 - halfer
    顺便说一下,当你看到针对你的消息时,请回复它们。我已经对这个问题进行了负评,并且在你回复后将取消负评。请愿意进行必要的编辑,以造福未来的读者。 - halfer
    3
    抱歉抱歉抱歉,我一直在忙一个非常严肃的项目,只有在有空的时候才会过来这里。顺便说一句,谢谢你的编辑,我会进行修改的。 - amdev

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接