国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

我的框架-Unity3d中的用戶數(shù)據(jù)儲存模塊UserDB

這篇具有很好參考價(jià)值的文章主要介紹了我的框架-Unity3d中的用戶數(shù)據(jù)儲存模塊UserDB。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

前言:

? ? ? ? 我們在開發(fā)一些小游戲的時(shí)候,不可能將所有的數(shù)據(jù)都上傳到服務(wù)器里去儲存,有很多數(shù)據(jù)是需要儲存到用戶本地的。比如一些簡單的用戶設(shè)置,一些只需要打開一次的用戶提示記錄等等。當(dāng)所需儲存的數(shù)據(jù)比較少的時(shí)候,我們可以直接用PlayerPrefs.SetString直接來儲存,但是這種方式每變化一次就需要執(zhí)行一次邏輯寫一行代碼,而且儲存的東西稍微多一點(diǎn)之后key就多了,對自己,對多人協(xié)同開發(fā)都是很麻煩的一件事。因此我們引入一套用戶的儲存類去儲存用戶數(shù)據(jù),將用戶的數(shù)據(jù)通過序列化的方式以json的格式儲存在用戶本地。接下來就是正文,我們將詳細(xì)介紹。

正文:

? ? ? ? 首先我們創(chuàng)建三個腳本:

????????DBManager(繼承自Unity的MonoBehaviour類,主要用于儲存因?yàn)樾枰玫経nity的生命周期函數(shù))

? ? ? ? DBUser(用戶儲存的主類,包括創(chuàng)建、讀取、儲存等方法)

? ? ? ? UserData(用于儲存用戶數(shù)據(jù)的結(jié)構(gòu)體,我們就是通過序列化這個類來儲存數(shù)據(jù))

第一步:先編寫一些DBUser的邏輯,上代碼:

public class DB_User
{
    #region 實(shí)例Inst
    private static DB_User _inst;
    public static DB_User Inst
    {
        get { return _inst; }
        private set { _inst = value; }
    }
    #endregion

    private string savePath = string.Empty;

    public DBManager dbManager;

    //構(gòu)造函數(shù)
    public DB_User()
    {
        _inst = this;
        InitDB();
        dbManager = new GameObject("DB").AddComponent<DBManager>();
    }

    private void InitDB()
    {
        CreateDBForder();
    }

    private void CreateDBForder()
    {
        string localPath = $"file://{Application.persistentDataPath}";
        savePath = localPath + "/gameDB/";
        try
        {
            if (Directory.Exists(savePath) == false)
            {
                Directory.CreateDirectory(savePath);
            }
        }
        catch { }
    }
}

????????這里主要就是完成DB的初始化問題,包括創(chuàng)建儲存的文件路徑,以及實(shí)例出DBManager。我們需要在游戲啟動時(shí)在適當(dāng)?shù)臅r(shí)候?qū)嵗鯠BUser即可。

    private void Start()
    {
        new DBUser();
    }

? ? ? ? 第二部:完成我們的UserData類。直接上代碼:

using Newtonsoft.Json;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UserData
{
    public static string type = "userdata";

    [NonSerialized]
    public bool save = false;

    #region 實(shí)例Inst
    private static UserData _inst;
    public static UserData Inst
    {
        get { return _inst; }
        set { _inst = value; }
    }
    #endregion

    #region 一些方法
    public void InitUserData()
    { 
        //TODO : 執(zhí)行一些新用戶需要執(zhí)行的方法
    }

    public string ToJson()
    {
        string str = string.Empty;
        str = JsonConvert.SerializeObject(this, Formatting.None);
        return str;
    }

    public UserData() { }
    #endregion


    private int _glod = 2000;

    //******************************************************************************//
    //********     注意:增加字段,一定要【設(shè)默認(rèn)值】且數(shù)組【不能賦值】    **********//
    //********          增加字段,private, 不要直接增加public              **********//
    //********          按照當(dāng)前的標(biāo)準(zhǔn)處理.否則可能無法存儲               **********//
    //******************************************************************************//

    //用戶的金幣數(shù)量
    public int glod { get { return _glod; } set { _glod = value; save = true; } }
}

????????稍微解釋下:

????????string type這個變量主要是區(qū)分儲存的類型的,這里是"userdata"主要就是本地儲存用戶數(shù)據(jù)的,將來可能還有數(shù)據(jù)庫儲存的類型,這里就不展開說了,本文只介紹本地儲存。覺著沒用的把它刪了就行,其他腳本里用到相關(guān)類型的一起改一下就好,覺得麻煩的就留著也沒有什么影響。

????????至于這個bool save這個變量主要是控制是否需要儲存的,我們每次修改值也就是Set的時(shí)候?qū)ave設(shè)為true,這樣在每次保存數(shù)據(jù)的時(shí)候如果沒有值的改變我們就不需要儲存數(shù)據(jù),這是提升性能的一個小技巧。

? ? ? ? ToJson這個方法就是將這個類序列化,返回一個字符串,這里我用的是Newtonsoft.Json。大家自己在github上找吧,我這里就不貼了。

? ? ? ? 我們這里不僅可儲存int、string、bool等基礎(chǔ)類型,也可以儲存List、Dictionary等數(shù)組、字典。也可以自己創(chuàng)建結(jié)構(gòu)體去儲存。可以說擴(kuò)展性非常的強(qiáng)。

? ? ? ? 第三部:有了我們的數(shù)據(jù)儲存類,就繼續(xù)完成我們的DBUser的讀取與儲存邏輯:

public class DB_User
{
    #region 實(shí)例Inst
    private static DB_User _inst;
    public static DB_User Inst
    {
        get { return _inst; }
        private set { _inst = value; }
    }
    #endregion

    private const string PLAYKEY = "db_";

    private string savePath = string.Empty;

    public DBManager dbManager;

    public DB_User()
    {
        _inst = this;
        InitDB();
        dbManager = new GameObject("DB").AddComponent<DBManager>();
    }

    public void SaveUser()
    {
        string queryModel = UserData.Inst.ToJson();
        Save(queryModel, UserData.type);
    }

    private void InitDB()
    {
        CreateDBForder();

        InitUserdata();
    }

    private void CreateDBForder()
    {
        string localPath = $"file://{Application.persistentDataPath}";
        savePath = localPath + "/gameDB/";
        try
        {
            if (Directory.Exists(savePath) == false)
            {
                Directory.CreateDirectory(savePath);
            }
        }
        catch { }
    }

    private void InitUserdata()
    {
        string queryModel = Read(UserData.type);
        Debug.Log("UserData : " + queryModel);
        if (!string.IsNullOrEmpty(queryModel))
        {
            UserData.Inst = JsonConvert.DeserializeObject<UserData>(queryModel);
        }
        else
        {
            // 無數(shù)據(jù)就創(chuàng)建新用戶
            UserData.Inst = new UserData();
            UserData.Inst.InitUserData();
        }
    }

    private string Read(string type)
    {
        string data = string.Empty;
        string name = PLAYKEY + type + ".dat";
        string filename = string.Format("{0}/{1}", savePath, name);
        if (FileExists(filename))
        {
            try
            {
                data = StreamReader(filename);
            }
            catch
            {
                Debug.LogError("存檔文件失敗 : " + filename);
            }
        }
        return data;
    }

    private void Save(string data, string type)
    {
        string name = PLAYKEY + type + ".dat";
        try
        {
            string filename = string.Format("{0}/{1}", savePath, name);
            StreamWriter(filename, data);
        }
        catch
        {
            Debug.LogError("存檔文件保存失?。? + name);
        }
    }

    #region Common
    /// <summary>
    /// 判斷文件是否存在
    /// </summary>
    /// <param name="path"></param>
    /// <returns></returns>
    private bool FileExists(string path)
    {
        path = ReplaceFileStart(path);
        return System.IO.File.Exists(path);
    }

    /// <summary>
    /// 替換FILE
    /// </summary>
    /// <param name="path"></param>
    /// <returns></returns>
    private string ReplaceFileStart(string path)
    {
        if (path.StartsWith("file://"))
        {
            path = path.Replace("file://", string.Empty);
        }
        return path;
    }

    /// <summary>
    /// 讀取文件
    /// </summary>
    /// <param name="path"></param>
    /// <returns></returns>
    private string StreamReader(string path)
    {
        path = ReplaceFileStart(path);
        if (FileExists(path))
        {
            try
            {
                System.IO.StreamReader sr = new System.IO.StreamReader(path);
                string jsonStr = sr.ReadToEnd();
                sr.Close();
                return jsonStr;
            }
            catch
            {
                Debug.LogError("讀取文件失敗 : " + path);
            }
        }
        return string.Empty;
    }

    /// <summary>
    /// 寫入儲存文件
    /// </summary>
    /// <param name="path"></param>
    /// <param name="data"></param>
    private void StreamWriter(string path, string data)
    {
        path = ReplaceFileStart(path);
        try
        {
            string forder = GetFileDirectory(path);
            bool exists = System.IO.Directory.Exists(forder);
            if (!exists)
            {
                System.IO.Directory.CreateDirectory(forder);
            }

            System.IO.StreamWriter sw = new System.IO.StreamWriter(path);
            sw.Write(data);
            //關(guān)閉StreamWriter
            sw.Close();
        }
        catch (System.Exception ee)
        {
            Debug.Log("文件寫入失敗:" + path + " Error:" + ee.Message);
        }
    }

    /// <summary>
    /// 替換格式
    /// </summary>
    /// <param name="path"></param>
    /// <returns></returns>
    private string GetFileDirectory(string path)
    {
        path = path.Replace("\\", "/");
        path = ReplaceFileStart(path);
        return System.IO.Path.GetDirectoryName(path);
    }
    #endregion
}

(數(shù)據(jù)加密這里我就不展開說了,這里只介紹儲存方法)?

? ? ? ? 最后就是處理DBManager了?:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DBManager : MonoBehaviour
{
    private float saveTimeout = 0;

    /// <summary>
    /// 用戶數(shù)據(jù)自動儲存時(shí)間
    /// </summary>
    public const float AUTOSAVETIME = 60f;

    private void Start()
    {
        DontDestroyOnLoad(this);
    }

    private void Update()
    {
        AutoSave();
    }

    private void OnApplicationFocus(bool focus)
    {
        if (!focus)
        {
            SaveData();
        }
    }

    private void SaveData()
    {
        if (UserData.Inst == null || DB_User.Inst == null) return;

        if (UserData.Inst.save)
        {
            DB_User.Inst.SaveUser();
            UserData.Inst.save = false;
        }
    }

    private void AutoSave()
    {
        if (Time.time > saveTimeout + AUTOSAVETIME)
        {
            saveTimeout = Time.time;
            SaveData();
        }
    }
}

????????這里就是每隔60s對用戶數(shù)據(jù)進(jìn)行一次本地的寫入儲存,如果用戶有脫離游戲焦點(diǎn)的行為是強(qiáng)制儲存一次。

結(jié)尾:

? ? ? ? 如何使用我們這個數(shù)據(jù)儲存模塊呢?

? ? ? ? 在正確的初始化之后,我們直接調(diào)用UserData就可以了。

        UserData.Inst.glod = 100;

? ? ? ? 再次進(jìn)入游戲之后就可看到在控臺輸出一個json:

{
	"glod": 96010
}

? ? ? ? 以上就是一個在本地進(jìn)行用戶數(shù)據(jù)儲存的一個模塊,歡迎大家一起討論。文章來源地址http://www.zghlxwxcb.cn/news/detail-413514.html

到了這里,關(guān)于我的框架-Unity3d中的用戶數(shù)據(jù)儲存模塊UserDB的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 如何將Unity3D中的腳本打包成為DLL類庫?

    如何將Unity3D中的腳本打包成為DLL類庫?

    如果我們想把代碼打成DLL,首先需要有一個Assembly和一個合理的代碼目錄結(jié)構(gòu)規(guī)劃。 1.將要?dú)w為一類的腳本放進(jìn)同一個文件內(nèi),在該文件夾下右鍵創(chuàng)建一個Assembly Definition,默認(rèn)它會將同文件夾以及子目錄內(nèi)的腳本歸為一個Assembly。 2.在Editor下創(chuàng)建一個CompileDll腳本來將我們的腳

    2024年02月12日
    瀏覽(28)
  • Unity3D中的C#協(xié)程(概念、使用方法、底層原理)

    ???????? Unity3D 中的協(xié)程是針對 Unity3D 框架和 C# 編程語言定制的 ,具有便捷的使用方式和良好的效率。其他語言Python、Lua等也支持協(xié)程,但是底層實(shí)現(xiàn)的細(xì)節(jié)可能不同。在 Unity3D 引擎中, 協(xié)程被 Unity3D?引擎的主循環(huán)所驅(qū)動 。 ????????協(xié)程(Coroutine)是一種編程概念

    2024年02月08日
    瀏覽(27)
  • 【Unity3D】Unity 3D 連接 MySQL 數(shù)據(jù)庫

    【Unity3D】Unity 3D 連接 MySQL 數(shù)據(jù)庫

    1.Navicat準(zhǔn)備 test 數(shù)據(jù)庫,并在test數(shù)據(jù)庫下創(chuàng)建 user 數(shù)據(jù)表,預(yù)先插入測試數(shù)據(jù)。 2.啟動 Unity Hub 新建一個項(xiàng)目,然后在Unity編輯器的 Project視圖 中,右擊新建一個 Plugins 文件夾將連接 MySQL的驅(qū)動包 導(dǎo)入(附加驅(qū)動包鏈接),之后Unity會自動引用它們。 3.在 Hierarchy視圖 中點(diǎn)擊

    2024年02月22日
    瀏覽(28)
  • ARM 在Unity3D 中的美術(shù)優(yōu)化解決方案                                   5.光照

    ARM 在Unity3D 中的美術(shù)優(yōu)化解決方案 5.光照

    (注意:雖然我們選擇了漸進(jìn) CPU 光照貼圖,但我們鼓勵你試用漸進(jìn) GPU 光照貼圖并進(jìn)行性能分析。根據(jù)系統(tǒng) GPU 的不同,性能可能會有所差異。) Unity 引擎提供了三個生成光照貼圖的選項(xiàng) - Enlighten、Progressive CPU lightmapper 和 Progressive GPU lightmapper。在本項(xiàng)目中,我們選擇使用漸

    2024年02月06日
    瀏覽(19)
  • Unity3D中UI Text中的部分文字添加特殊顏色突出

    Unity3D中UI Text中的部分文字添加特殊顏色突出

    為了突顯某些文字,數(shù)據(jù)的重要性,文字會以變換顏色的方式來體現(xiàn): 在Unity3D 中,通常會通過改變文本的顏色,來改變字體的顏色。但如果是要在這個文本的字符串的某個詞 改變顏色,color屬性暫時(shí)實(shí)現(xiàn)不了。 具體實(shí)現(xiàn)實(shí)現(xiàn)方法可以在字符串中,讓部分字符添加顏色,顏色

    2024年02月07日
    瀏覽(23)
  • 使用Unity連接MySQL數(shù)據(jù)庫(Unity3D)

    在Unity開發(fā)中,連接數(shù)據(jù)庫是非常常見且重要的任務(wù)之一。本文將介紹如何在Unity中連接MySQL數(shù)據(jù)庫,并提供相應(yīng)的源代碼示例。 步驟1:準(zhǔn)備工作 在開始之前,確保你已經(jīng)安裝了Unity編輯器,并且有一個MySQL數(shù)據(jù)庫可供連接。你可以使用XAMPP等工具來搭建本地的MySQL服務(wù)器,或

    2024年02月04日
    瀏覽(24)
  • 【Unity3D】UI Toolkit數(shù)據(jù)動態(tài)綁定

    【Unity3D】UI Toolkit數(shù)據(jù)動態(tài)綁定

    ????????本文將實(shí)現(xiàn) cvs 表格數(shù)據(jù)與 UI Toolkit 元素的動態(tài)綁定。 ????????如果讀者對 UI Toolkit 不是太了解,可以參考以下內(nèi)容。 UI Toolkit簡介 UI Toolkit容器 UI Toolkit元素 UI Toolkit樣式選擇器 UI Toolkit自定義元素 ? ? ? ? 本文完整資源見→UI Toolkit數(shù)據(jù)動態(tài)綁定。 2.1?UI 搭建

    2024年02月08日
    瀏覽(90)
  • 以unity3d為例解讀:游戲數(shù)據(jù)加密

    以unity3d為例解讀:游戲數(shù)據(jù)加密

    目錄 前言 1、Virbox 一、Virbox 是怎么做的? 1、如何對程序進(jìn)行保護(hù)? 2、如何對資源進(jìn)行保護(hù)? 3、使用加密工具前后比較 二、Virbox 保護(hù)方案特點(diǎn) l?更安全 l?更全面 l?更簡單 2、DES和RSA加密算法 一、DES加密算法 二、RSA加密算法 RSA加密算法的基本流程如下: 網(wǎng)絡(luò)游戲數(shù)據(jù)文

    2024年02月02日
    瀏覽(95)
  • Unity3D學(xué)習(xí)之?dāng)?shù)據(jù)持久化——PlayerPrefs

    Unity3D學(xué)習(xí)之?dāng)?shù)據(jù)持久化——PlayerPrefs

    就是保存存檔和讀取存檔。 分為兩部分,存儲和讀取,先看存儲在看讀取 PlayerPrefs 是unity提供可以存儲和讀取玩家數(shù)據(jù)的公共類 上面定義過 PlayerPrefs.SetInt(“myAge”,18) 后面再定義PlayerPrefs.SetFloat(“myAge”,20.2f) 后面進(jìn)行讀取int型 myAge時(shí),會變成默認(rèn)值0 打印結(jié)果 0 和 100 1)父

    2024年01月18日
    瀏覽(53)
  • Unity3D學(xué)習(xí)之?dāng)?shù)據(jù)持久化——XML

    Unity3D學(xué)習(xí)之?dāng)?shù)據(jù)持久化——XML

    最終達(dá)到的效果 樹形結(jié)構(gòu) 屬性通過空格隔開 屬性名 = 引導(dǎo)包裹的內(nèi)容 這兩個代表的東西是一樣的 可以在菜鳥上使用xml驗(yàn)證器 xml驗(yàn)證器 在Resources文件夾創(chuàng)建一個xml文件 把文件再復(fù)制到streamingAsserts 3.2.1 通過Resources文件進(jìn)行讀取 3.2.2 通過xml文件進(jìn)行加載 獲取根節(jié)點(diǎn) 遍歷同名

    2024年01月23日
    瀏覽(18)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包