簡體   English   中英

Unity中的序列化

[英]Serialization in Unity

因此,盡可能簡短地講,我試圖保存角色的基本信息,不僅聽說過PlayerPrefs的建議不正確,而且也不適用於我所擁有的某些信息(例如,我不能PlayerPrefs我的職業及其附帶的統計信息和繼承的類信息),因此我已經假設最好的(即使不是唯一的)方式是通過序列化。

現在,我非常肯定我以一種核心的方式理解了序列化,但是我不會聲稱我非常了解它,因此,我有點束縛。

我寫了很多腳本, 這是它們的要旨 注意:我的腳本可能很好,但是如果是這樣,請告訴我。 我並不是說它們很棒,只是我在那里有很多東西,而且AFAIK,它們都還不錯,無論出於什么原因,僅僅進行序列化對我來說都是困難的。

對它們的簡要說明:我只是想為Guard創建一個角色腳本,該腳本將同時使用Job:Mercenary和Type:GuardPrototype,然后,我希望能夠保存該腳本。 從理論上講,GameControl.cs腳本可以實現這一點,但是我遇到了麻煩(很明顯),並且由於我很笨拙,我不得不注釋很多事情。

就是說,我確實從Unity編寫了Persistence and Saving教程,但是我不僅使用/調用了不同的腳本,而且我沒有處理簡單的float,因此我很難修改它。 最終,我只想知道兩件事:我試圖保存的代碼是否明智? 如果是,那么我將如何使用序列化來保存信息?

在此先感謝,感謝您的幫助。

TL; DR序列化如何處理不是簡單浮點數的單獨腳本中的東西?

注意:以下是我打算使用的腳本鏈

  • ClassParadigm->佣工//這是被使用的工作
  • TypeParadigm //因為可能有多個-> StandardParadigm-> GuardPrototype //所有標准類型,它是一個保護對象

然后,我想有一個腳本調用它們。 -角色(在本例中為GuardA)和一個類型(均在上面建立),然后將要完成工作,以及StandardPlayerParadigm //一個標准玩家將擁有什么

最后,所有這些都應該放在Unity中的一個對象上,然后我可以對其進行預制。 因此,換句話說,如果這是我游戲中的角色,那么每當預制件出現在現場時,它就是GuardPrototype + Mercenary。

編輯:感謝Mike Hunt,因為他們肯定可以幫助我解決主要問題。 我現在有一個稍微不同的問題,但這似乎更可行。

首先, 我更新了要點。 其次,我在Unity中遇到了一個問題,當我將XMLSerialization腳本附加到gameObject時,它具有一些子配置文件(例如我不希望它具有的嵌套菜單)。 我不太確定該如何解決這個問題,而且由於這種情況,它似乎似乎實際上並沒有在分配我想要的值(因為我希望GuardA腳本從其“類型”分配統計信息”是我寫的腳本,但我認為它不起作用)。 我很肯定我只是做了一些多余的事情,並且在代碼中的某處使它變得多余了,但是我無法終生弄清楚那會是什么。

現在有兩個問題:A)這是怎么回事? B)這有效嗎? 我不是完全按照預期實現了嗎?

還有,第三個問題:這是一個重復的敵人,其統計數據上的差異很小,這似乎是一種無可挑剔的方法,但是僅保存我的標准玩家我該怎么辦? 似乎還沒有達到目標,但我可能是錯的,只是沒有意識到。

如果要使用二進制序列化,那將是實現ISerializable的最佳方法。 您需要提供2個項目:

  1. 序列化的方法,它將指導序列化程序“什么”和“如何”保存:

無效的GetObjectData(SerializationInfo info,StreamingContext context)

  1. 自定義構造器。 ISerializable接口暗示帶有簽名構造函數的構造函數

(SerializationInfo信息,StreamingContext上下文)

如果需要另一示例文章“ 對象序列化”

但是對於游戲,我會很樂意看一些基於Xml的自定義serizaliser,因此您不需要為每個類更改編寫二進制序列化的說明,而只需編寫所需的屬性。 Ofc Unity中的Properties可能會有一些麻煩:(。

創建一個類,該類將存儲信息以保存和裝飾Serializable屬性:

[Serializable]
public class Storage{
    public string name;
    public int score;
}

當您要保存數據時,請創建此類的實例,填充該類,使用.NET序列化並使用PlayerPrefs保存:

// Create
Storage storage = new Storage();
// Populate
storage.name = "Geoff";
storage.score = 10000;
// .NET serialization 
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, items as Storage);
// use PlayerPrefs
PlayerPrefs.SetString("data", Convert.ToBase64String(ms.GetBuffer()));

您可以通過反轉過程進行檢索:

if (PlayerPrefs.HasKey("data") == false) { return null; }
string str = PlayerPrefs.GetString("data");
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream(Convert.FromBase64String(str));
Storage storage =  bf.Deserialize(ms) as Storage;

我建議將其轉換為通用方法,以便您可以使用具有任何鍵的任何類型:

public static class Save 
{
    public static void SaveData<T>(string key, object value) where T : class
    {
        BinaryFormatter bf = new BinaryFormatter();
        MemoryStream ms = new MemoryStream();
        bf.Serialize(ms, value as T);
        PlayerPrefs.SetString(key, Convert.ToBase64String(ms.GetBuffer()));
    }

    public static T GetData<T>(string key) where T: class
    {
        if (PlayerPrefs.HasKey(key) == false) { return null; }
        string str = PlayerPrefs.GetString(key);
        BinaryFormatter bf = new BinaryFormatter();
        MemoryStream ms = new MemoryStream(Convert.FromBase64String(str));
        return bf.Deserialize(ms) as T;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM