Unity中的JsonManager

1.具體代碼

先貼代碼

using LitJson;
using System.IO;
using UnityEngine;/// <summary>
/// 序列化和反序列化Json時  使用的是哪種方案    有兩種  JsonUtility 不能直接序列化字典  ligJson可以序列化字典 
/// </summary>
public enum JsonType
{JsonUtility,LitJson,Newtonsoft,
}/// <summary>
/// Json數據管理類 主要用于進行 Json的序列化存儲到硬盤 和 反序列化從硬盤中讀取到內存中
/// </summary>
public class JsonMgr : SingleTon<JsonMgr>
{public JsonMgr(){}//存儲Json數據 序列化public void SaveData(object data, string fileName, string directPath = "", JsonType type = JsonType.Newtonsoft){//確定存儲路徑string directoryPath = Application.persistentDataPath + "/" + directPath;string filePath = directoryPath + fileName + ".json";//序列化 得到Json字符串string jsonStr = "";switch (type){case JsonType.JsonUtility:jsonStr = JsonUtility.ToJson(data);break;case JsonType.LitJson:jsonStr = JsonMapper.ToJson(data);break;case JsonType.Newtonsoft:jsonStr = Newtonsoft.Json.JsonConvert.SerializeObject(data);break;}if (!Directory.Exists(directoryPath)){Directory.CreateDirectory(directoryPath);}//把序列化的Json字符串 存儲到指定路徑的文件中File.WriteAllText(filePath, jsonStr);}//讀取指定文件中的 Json數據 反序列化public T LoadData<T>(string filePath, JsonType type = JsonType.Newtonsoft) where T : new(){//數據對象T data = new T();//確定從哪個路徑讀取//首先先判斷 默認數據文件夾中是否有我們想要的數據 如果有 就從中獲取string path = Application.streamingAssetsPath + "/" + filePath + ".json";//先判斷 是否存在這個文件//如果不存在默認文件 就從 讀寫文件夾中去尋找if (!File.Exists(path))path = Application.persistentDataPath + "/" + filePath + ".json";//如果讀寫文件夾中都還沒有 那就返回一個默認對象if (!File.Exists(path))return data;//進行反序列化string jsonStr = File.ReadAllText(path);switch (type){case JsonType.JsonUtility:data = JsonUtility.FromJson<T>(jsonStr);break;case JsonType.LitJson:data = JsonMapper.ToObject<T>(jsonStr);break;case JsonType.Newtonsoft:data = Newtonsoft.Json.JsonConvert.DeserializeObject<T>(jsonStr);break;}//把對象返回出去return data;}
}

2.使用示例

保存玩家數據

// 定義數據類
[Serializable]
public class PlayerData {public string name;public int level;
}// 保存數據
PlayerData data = new PlayerData { name = "Alice", level = 10 };
JsonMgr.Instance.SaveData(data, "player", "Save/", JsonType.Newtonsoft);

加載玩家數據

// 加載數據
PlayerData loadedData = JsonMgr.Instance.LoadData<PlayerData>("Save/player", JsonType.Newtonsoft);
Debug.Log($"Name: {loadedData.name}, Level: {loadedData.level}");

再補充一下一般我實際的使用方法

[System.Serializable] // 添加可序列化標簽
public class GameData
{public bool openLevel2 = false;public bool openLevel3 = false;public bool openLevel4 = false;public bool openLevel5 = false;public bool openCustom = false;
}public class LevelManager : MonoBehaviour
{// 添加當前游戲數據引用public GameData currentGameData;private const string SAVE_FILE_NAME = "GameSaveData";private void Start(){GameDataInit();}/// <summary>/// 讀取玩家信息,沒有則創建/// </summary>private void GameDataInit(){// 從JSON加載數據currentGameData = JsonMgr.Instance.LoadData<GameData>(SAVE_FILE_NAME);Debug.Log("持久化數據路徑: " + Application.persistentDataPath);// 如果沒有存檔數據,創建新數據if (currentGameData == null){currentGameData = new GameData();Debug.Log("創建新的游戲存檔");}}/// <summary>/// 保存游戲數據到JSON/// </summary>public void SaveGameData(){JsonMgr.Instance.SaveData(currentGameData, SAVE_FILE_NAME);Debug.Log("游戲數據已保存");}}

?把這個腳本設置成單例或者在合適的地方調用SaveGameData,存儲你想保存的類,這樣可以自動創建json自動讀取,只需要在合適的地方存檔就好了

3.核心功能

  • 多方案支持

    JsonType?枚舉:支持三種 JSON 序列化/反序列化方案:
    • Newtonsoft(Json.NET):功能強大的第三方庫,支持復雜類型和更多特性。
    • LitJson:第三方庫,支持字典等復雜類型。
    • JsonUtility:Unity 內置方案,不支持字典等復雜類型。
  • 數據存儲與讀取

    • SaveData?方法:將對象序列化為 JSON 字符串并保存到指定路徑。
    • LoadData<T>?方法:從指定路徑讀取 JSON 文件并反序列化為對象。

4.代碼結構解析

1. 構造函數

public JsonMgr() { }

  • 單例類的默認構造函數,無特殊邏輯。

2. 保存數據方法?SaveData

public void SaveData(object data, string fileName, string directPath = "", JsonType type = JsonType.Newtonsoft)
  • 參數說明

    • data:要保存的對象。
    • fileName:文件名(不含?.json?后綴)。
    • directPath:可選的子目錄路徑。
    • type:序列化方案(默認使用?Newtonsoft)。
  • 邏輯流程

    1. 確定存儲路徑
      • 使用?Application.persistentDataPath(可讀寫路徑)構建完整路徑。
      • 示例:/Users/xxx/Library/Application Support/Unity/.../directPath/fileName.json
    2. 序列化
      • 根據?type?使用對應方案將對象轉換為 JSON 字符串。
      • JsonUtilityJsonUtility.ToJson(data)
      • LitJsonJsonMapper.ToJson(data)
      • NewtonsoftJsonConvert.SerializeObject(data)
    3. 創建目錄:若目錄不存在則創建。
    4. 寫入文件:使用?File.WriteAllText(filePath, jsonStr)?存儲數據。

3. 讀取數據方法?LoadData<T>

public T LoadData<T>(string filePath, JsonType type = JsonType.Newtonsoft) where T : new()
  • 參數說明

    • filePath:文件路徑(不含?.json?后綴)。
    • type:反序列化方案(默認使用?Newtonsoft)。
    • 泛型約束?where T : new():確保類型?T?有無參構造函數。
  • 邏輯流程

    1. 優先從只讀路徑加載
      • 首先檢查?Application.streamingAssetsPath(只讀路徑,通常用于默認配置文件)。
      • 如果文件不存在,嘗試從?Application.persistentDataPath(用戶數據路徑)加載。
    2. 若文件不存在:返回默認的?T?實例(通過?new T()?創建)。
    3. 反序列化
      • 根據?type?使用對應方案將 JSON 字符串轉換為對象。
      • JsonUtilityJsonUtility.FromJson<T>(jsonStr)
      • LitJsonJsonMapper.ToObject<T>(jsonStr)
      • NewtonsoftJsonConvert.DeserializeObject<T>(jsonStr)

關鍵點分析

1. 路徑選擇與平臺兼容性

  • Application.persistentDataPath
    • 可讀寫路徑,適合保存用戶數據(如玩家進度、配置等)。
  • Application.streamingAssetsPath
    • 只讀路徑,通常用于打包后的默認資源(如初始配置文件)。
    • 注意:在某些平臺(如 Android)上,File.ReadAllText?無法直接訪問此路徑的文件,需通過?UnityWebRequest?或?WWW?加載。當前代碼可能在此類平臺上拋出異常。

2. 默認值處理

  • 若文件不存在,返回?new T()?創建的默認對象。適用于需要保證最小功能的場景(如游戲配置加載失敗時使用默認值)。

3. 異常處理缺失

  • 當前代碼未處理文件讀寫或序列化/反序列化過程中可能出現的異常(如 IO 錯誤、格式錯誤)。建議添加?try-catch?塊并記錄日志。

4. 性能優化建議

  • 異步操作:大量數據讀寫可能阻塞主線程,可改用異步方法(如?File.ReadAllTextAsync?/?File.WriteAllTextAsync)。
  • 緩存機制:對頻繁讀取的數據(如配置文件),可考慮緩存反序列化后的對象。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/82220.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/82220.shtml
英文地址,請注明出處:http://en.pswp.cn/web/82220.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

50天50個小項目 (Vue3 + Tailwindcss V4) ? | Split Landing Page(拆分展示頁)

&#x1f4c5; 我們繼續 50 個小項目挑戰&#xff01;—— SplitLandingPage 組件 倉庫地址&#xff1a;https://github.com/SunACong/50-vue-projects 項目預覽地址&#xff1a;https://50-vue-projects.vercel.app/ 在這篇文章中&#xff0c;我們將實現一個交互式的左右面板…

機器學習-ROC曲線?? 和 ??AUC指標

1. 什么是ROC曲線&#xff1f;?? ROC&#xff08;Receiver Operating Characteristic&#xff0c;受試者工作特征曲線&#xff09;是用來評估??分類模型性能??的一種方法&#xff0c;特別是針對??二分類問題??&#xff08;比如“患病”或“健康”&#xff09;。 ?…

Docker容器創建Redis主從集群

利用虛擬機中的三個Docker容器創建主從集群&#xff0c;容器信息&#xff1a; 容器名角色IP映射端口r1master192.168.150.1017001r2slave192.168.150.1017002r3slave192.168.150.1017003 啟動多個redis實例 新建一個docker-compose文件來構建主從集群&#xff1a; 文件內容&…

手寫ArrayList和LinkedList

項目倉庫&#xff1a;https://gitee.com/bossDuy/hand-tear-collection-series 基于b站up生生大佬&#xff1a;https://www.bilibili.com/video/BV1Kp5tzGEc5/?spm_id_from333.788.videopod.sections&vd_source4cda4baec795c32b16ddd661bb9ce865 LinkedList package com…

每日c/c++題 備戰藍橋杯(Cantor 表)

Cantor 表的探究與實現 在數學中&#xff0c;有理數的可枚舉性是一個令人驚嘆的結論。今天&#xff0c;就讓我們一起深入探討這個經典問題&#xff0c;并分享一段精心編寫的代碼&#xff0c;揭開這一數學奧秘的神秘面紗。 問題背景 在 19 世紀末&#xff0c;偉大的數學家康托…

解決idea與springboot版本問題

遇到以下問題&#xff1a; 1、springboot3.2.0與jdk1.8 提示這個包org.springframework.web.bind.annotation不存在&#xff0c;但是pom已經引入了spring-boot-starter-web 2、Error:Cannot determine path to tools.jar library for 17 (D:/jdk17) 3、Error:(3, 28) java: …

Notepad++找回自動暫存的文件

場景&#xff1a; 當你沒有保存就退出Notepad&#xff0c;下次進來Notepad會自動把你上次編輯的內容顯示出來&#xff0c;以便你繼續編輯。除非你手動關掉當前頁面&#xff0c;這樣Notepad就會刪除掉自動保存的內容。 問題&#xff1a; Notepad會將自動保存的文件地址,打開Note…

yolov12畢設前置知識準備 1

1 什么是目標檢測呢&#xff1f; 目標檢測&#xff08;Object Detection&#xff09;主要用于識別圖像或視頻中特定類型物體的位置&#xff0c;并標注其類別。 簡單來說&#xff0c;就是讓計算機像人類一樣 “看懂” 圖像內容&#xff0c;不僅能識別出物體&#xff08;如人、…

unix/linux source 命令,其內部結構機制

要理解 source (或 .) 命令的內部結構機制,我們需要戴上“操作系統”和“解釋器設計”的眼鏡,深入到 Shell 如何管理其狀態以及如何執行命令的層面。 雖然我們無法直接看到 Shell 內部的 C 代碼(除非我們去閱讀 Bash 或 Zsh 的源碼),但我們可以基于其行為和操作系統的原理…

計算機網絡學習20250528

地址解析協議ARP 實現IP地址和Mac地址的轉換 ARP工作原理&#xff1a; 每臺主機或路由器都有一個ARP表&#xff0c;表項&#xff1a;<IP地址&#xff0c;Mac地址&#xff0c;TTL>&#xff08;TTL一般為20分鐘&#xff09; 主機產生ARP查詢分組&#xff0c;包含源目的IP地…

【Rust】Rust獲取命令行參數以及IO操作

?? 歡迎大家來到景天科技苑?? &#x1f388;&#x1f388; 養成好習慣&#xff0c;先贊后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者簡介&#xff1a;景天科技苑 &#x1f3c6;《頭銜》&#xff1a;大廠架構師&#xff0c;華為云開發者社區專家博主&#xff0c;…

微服務中引入公共攔截器

本文使用的微服務版本為springcloudAlbaba :2021.0.4.0 微服務工程&#xff0c;一般公共的東西都放入一個工程&#xff0c;別的微服務都會引入這個工程&#xff0c;比如common-service,那么就可以在這個工程編寫一個攔截器&#xff1a;&#xff0c;比如&#xff1a; public cla…

Linux SLES 系統的/var/log/下的常見文件及其作用

在 SUSE Linux Enterprise Server&#xff08;SLES&#xff09; 系統中&#xff0c;/var/log/ 目錄是系統日志的集中地&#xff0c;存儲了各種服務、內核、系統消息的日志。以下是一些在 /var/log/ 下常見的日志文件及其功能&#xff1a; &#x1f4c2; 常見日志文件及功能 文…

oracle goldengate同步SQL server到SQL server的實時數據同步

參考文檔 https://docs.oracle.com/en/middleware/goldengate/core/19.1/oggmp/oracle-goldengate-classic-sql-server.html#GUID-948C5BEE-E7A0-4CE2-BE09-F83145677D18 https://docs.oracle.com/en/middleware/goldengate/core/21.3/ggcab/other-programs-and-settings-sql-…

語音轉文字工具

平時工作和學習比較忙&#xff0c;可能沒時間聽講座&#xff0c;只能看回放&#xff0c;回訪也很長&#xff0c;這時&#xff0c;我們可以借助語言轉文字&#xff0c;通過閱讀文字快速了解講座的重點&#xff0c;今天給大家分享一個本人經常用的語言轉文字工具&#xff0c;改工…

硬件實時時鐘(RTC)

硬件實時時鐘&#xff08;RTC&#xff09;詳解 硬件實時時鐘&#xff08;Real-Time Clock&#xff0c;RTC&#xff09;是計算機主板上的一個獨立計時芯片&#xff0c;用于在系統關機后持續記錄時間。它不依賴操作系統&#xff0c;由紐扣電池&#xff08;如CR2032&#xff09;供…

pycharm debug的時候無法debug到指定的位置就停住不動了

報錯大致是這樣的&#xff0c;但是直接run沒有問題&#xff0c;debug就停住不動了 Traceback (most recent call last): File "/home/mapengsen/.pycharm_helpers/pydev/_pydevd_bundle/pydevd_comm.py", line 467, in start_client s.connect((host, port)) Timeou…

Python6.1打卡(day33)

DAY 33 MLP神經網絡的訓練 知識點回顧&#xff1a; 1.PyTorch和cuda的安裝 2.查看顯卡信息的命令行命令&#xff08;cmd中使用&#xff09; 3.cuda的檢查 4.簡單神經網絡的流程 1.數據預處理&#xff08;歸一化、轉換成張量&#xff09; 2.模型的定義 …

NodeJS全棧開發面試題講解——P11消息隊列(MQ)

? 11.1 為什么要用消息隊列&#xff1f;在哪些場景下最適合&#xff1f; ? 作用&#xff1a; 削峰填谷&#xff1a;緩解高并發壓力&#xff0c;異步處理任務&#xff08;如秒殺下單 → MQ → 異步扣庫存&#xff09; 解耦服務&#xff1a;上下游解耦&#xff08;如下單服務…

mysql執行sql語句報錯事務鎖住

報錯情況 1205 - Lock wait timeout exceeded; try restarting transaction先找出長時間運行的事務 SELECT * FROM information_schema.INNODB_TRX ORDER BY trx_started ASC;終止長時間運行的事務 KILL [PROCESS_ID];