Related Posts Plugin for WordPress, Blogger...

5-5 Inventory System - Using JSON

本章開始要來製作背包系統,背包系統包含玩家的背包、倉庫、裝備、人物屬性、鍛造合成、商店功能等等,接下來的教學會一步一步製作遊戲的背包系統,並嘗試將原本寫好的武器系統改寫並納入背包中。

首先簡單介紹一下我的背包系統使用JSON格式記錄每個物件的資料,Unity內建JsonUtility解析JSON格式,若有不了解的地方,請先看看以下文章:

[UNITY] 使用內建的JSONUTILITY 遊戲讀存檔案 --2017.11.20更新
http://sammaru.blogspot.tw/2017/03/unity-jsonutility.html

JSON Serialization
https://docs.unity3d.com/Manual/JSONSerialization.html

當然大家也可以考慮使用XML、SQL、NoSQL等各種不同的資料儲存方式,我認為使用JSON傳輸資料最方便,需要透過網路更新時,使用Web Service的方式取得JSON資料,再寫入到本地的資料庫中。XML格式也可以考慮,但是撰寫的格式繁瑣了點,而且目前最流行的規格是JSON嘛!

先來自行寫一個簡單的JSON資料吧,取名叫Items.json,並放在Resources資料夾中。我們會使用Resource.Load方法讀取JSON資料。

Items.json:

{"ItemEntityList":[
{
    "ID":1,
    "Name":"血量瓶",
    "ItemTypeString":"Consumable",
    "ItemQualityString":"Common",
    "Description":"+ 25 HP",
    "Capacity":10,
    "BuyPrice":10,
    "SellPrice":10,
    "Sprite":"Sprites/Items/hp",
    "HP":10,
    "MP":0
},
{
    "ID":1,
    "Name":"能量瓶",
    "ItemTypeString":"Consumable",
    "ItemQualityString":"Common",
    "Description":"+ 50 MP",
    "Capacity":10,
    "BuyPrice":10,
    "SellPrice":10,
    "Sprite":"Sprites/Items/mp",
    "HP":0,
    "MP":10
}
]}

然後新增五個Script,分別是負責讀取資料的InventorySystem.cs、物件的基礎類別Item.cs、消耗品Consumable.cs、裝備Equipment.cs、鍛造素材Materials.cs。

以下提供程式碼,說明也寫在註解中了,這一步驟沒有很難就不需要太多說明。
InventorySystem.cs:

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

namespace RPG.Inventory{
 public class InventorySystem : MonoBehaviour {

  ItemList itemList;

  void Start () {
   ParseItemsJson ();
  }
  
  void Update () {
   
  }

  private void ParseItemsJson(){
   // 從Resource資料夾中讀取Items.json
   TextAsset json = Resources.Load ("Items");
   // 解析Json格式
   itemList = JsonUtility.FromJson (json.text);
   // 使用foreach迴圈讀取List中的Item資料
   foreach (Item entity in itemList.ItemEntityList) {
    print (entity.Name);
    print (entity.Type);
    print (entity.Quality);
    print (entity.Sprite);
   }
  }
 }
}

Item.cs:

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

namespace RPG.Inventory{
 [Serializable]
 public class ItemList{
  public List ItemEntityList;
 }

 [Serializable]
 public class Item : ISerializationCallbackReceiver{
  public int ID;
  public string Name;
  public string ItemTypeString;
  public string ItemQualityString;
  // 目前Unity提供的JsonUtility不支援enum型別的轉換,所以此處指定為NonSerialized代表不解析
  [NonSerialized] public ItemType Type;
  [NonSerialized] public ItemQuality Quality;
  public string Description;
  public int Capacity;
  public int BuyPrice;
  public int SellPrice;
  public string Sprite;

  public void OnAfterDeserialize(){
   // JSON格式解析後,將ItemTypeString,ItemQualityString轉換成enum型別
   Type = (ItemType)System.Enum.Parse (typeof(ItemType), ItemTypeString);
   Quality = (ItemQuality)System.Enum.Parse (typeof(ItemQuality), ItemQualityString);
  }

  public void OnBeforeSerialize(){}
 }

 public enum ItemType{
  Consumable,
  Equipment,
  Weapon,
  Material
 }

 public enum ItemQuality{
  Common,
  Uncommon,
  Rare,
  Epic,
  Legendary,
  Artifact
 }
}

Consumable.cs:

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

namespace RPG.Inventory{
 [Serializable]
 public class Consumable{
  public int HP;
  public int MP;
 }
}

Equipment.cs:

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

namespace RPG.Inventory{
 [Serializable]
 public class Equipment : ISerializationCallbackReceiver {
  public int Strength;
  public int Intellect;
  public int Agility;
  public int Stamina;
  public string EquipmentTypeString;
  [NonSerialized] public EquipmentType TheEquipmentType;

  public void OnAfterDeserialize(){
   TheEquipmentType = (EquipmentType)System.Enum.Parse (typeof(EquipmentType), EquipmentTypeString);
  }

  public void OnBeforeSerialize(){}
 }

 public enum EquipmentType{
  Head,
  Neck,
  Ring,
  Leg,
  Bracer,
  Boots,
  Trinket,
  Shoulder,
  Belt,
  OffHand
 }
}


Materials.cs:

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

namespace RPG.Inventory{
 [Serializable]
 public class Material : Item {

 }
}

於場景中新增一個Empty GameObject取名為InventorySystem。

將InventorySystem.cs拉進去。

 執行遊戲後,從console視窗可以確認是否正確解析JSON資料。




留言