2017-06-02 103 views
3

我正在學習一個教程,我需要保存屬於一個對象的精靈。 我正在創建一個項目的數據庫,當然想要正確的圖像來與該項目。這是我建立了我的項目數據庫:Unity:保存/加載精靈作爲Json

ItemObject

[System.Serializable] 
public class ItemObject{ 

    public int id; 
    public string title; 
    public int value; 
    public string toolTip; 
    public bool stackable; 
    public string category; 
    public string slug; 
    public Sprite sprite; 


    public ItemObject(int id, string title, int value, string toolTip, bool stackable, string category, string slug) 
    { 
     this.id = id; 
     this.title = title; 
     this.value = value; 
     this.toolTip = toolTip; 
     this.stackable = stackable; 
     this.category = category; 
     this.slug = slug; 
     sprite = Resources.Load<Sprite>("items/" + slug); 
    } 

的ItemData

[System.Serializable] 
public class ItemData { 

    public List<ItemObject> itemList; 

} 

我然後保存/載入ItemData.itemList。這很好。正如你所看到的,我使用「slug」來加載我的物品的精靈,slug基本上是一個代碼友好的名字(例如:golden_hat),然後我的Sprite的名字相同。

這也很好,但Unity會保存Sprite InstanceID,它始終會在啓動時更改,所以如果我退出Unity並加載數據,它將會得到錯誤的圖像。

我的JSON:

{ 
    "itemList": [ 
     { 
      "id": 0, 
      "title": "Golden Sword", 
      "value": 111, 
      "toolTip": "This is a golden sword", 
      "stackable": false, 
      "category": "weapon", 
      "slug": "golden_sword", 
      "sprite": { 
       "instanceID": 13238 
      } 
     }, 
     { 
      "id": 1, 
      "title": "Steel Gloves", 
      "value": 222, 
      "toolTip": "This is steel gloves", 
      "stackable": true, 
      "category": "weapon", 
      "slug": "steel_gloves", 
      "sprite": { 
       "instanceID": 13342 
      } 
     } 
    ] 
} 

所以我猜測它不會工作到做這種方式,有一些其他的方式來保存的Json雪碧?或者我必須每次使用我的「slug」在運行時加載正確的Sprite?

+0

你**不應**在遊戲中保存精靈。您應該使用AssetBundles或資源API。至於保存它,保存AssetBundles或[資源](https://stackoverflow.com/a/41326276/3785314)文件夾的路徑** – Programmer

+0

@Programmer謝謝,我現在保存資源文件夾的路徑。並開始尋找AssetBundles。 – Majs

回答

0

更合適的方法是將紋理保存爲byte [],然後您的json包含byte []的名稱或url。

{ 
     "id": 1, 
     "title": "Steel Gloves", 
     "value": 222, 
     "toolTip": "This is steel gloves", 
     "stackable": true, 
     "category": "weapon", 
     "slug": "steel_gloves", 
     "sprite": "steelgloves" 
    } 

然後,當你抓住JSON,你轉換爲C#和查找字節數組。一旦你的字節數組,你可以重建精靈:如果您使用JsonUtility系列化

byte [] bytes = File.ReadAllBytes(path); 
Texture2d tex = new Texture2D(4,4); 
tex.LoadImage(bytes); 
Sprite sp = Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), new Vector2(0.5f,0.5f)); 
+0

接受它cus它回答我的問題。但是我只想將路徑保存到Resources資源:) – Majs

1

,你可以以接收串行化的回調實現ISerializationCallbackReceiver。這樣,您可以在對象被反序列化之後,根據存儲的路徑加載正確的精靈。你也將避免資源重複。

[Serializable] 
public class ItemObject : ISerializationCallbackReceiver 
{ 
    public void OnAfterDeserialize() 
    { 
     sprite = Resources.Load<Sprite>("items/" + slug); 
     Debug.Log(String.Format("Loaded {0} from {1}", sprite, slug)); 
    } 

    public void OnBeforeSerialize() { } 

    (...) 
} 

如果你真的直接存儲精靈的JSON,考慮序列化從Sprite.texture.GetRawTextureData()拍攝的原始紋理數據(可能存儲在base64 string二進制數據),並使用Sprite.Create()在運行時重新創建它。 ISerializationCallbackReceiver技巧也適用於此。作爲一個附加說明,如果它符合您的要求,絕對考慮放棄基於JSON的對象數據庫而傾向於使用Scriptable Objects。這樣,您可以輕鬆引用UnityEngine對象,而無需訴諸使用Resources文件夾(除非必要,否則不推薦)。

+0

謝謝,+1提到ScriptableObjects。但據我所知,這些在內部得到保護。我希望玩家能夠在沒有太多問題的情況下修改我的遊戲。 Json非常適合 – Majs