Related Posts Plugin for WordPress, Blogger...

5-7 Storing Items In Slot

今天要來製作放置物品到背包內的功能,由於背包系統是一系列的文章,請大家先把前面的文章都依序看完唷,從下列這篇開始看:
5-5 Inventory System - Using JSON
https://rpgcorecombat.blogspot.tw/2018/01/5-5-inventory-system-using-json.html

首先我在之前的文章中,為了測試JSON讀取的效果而在場景中放置了一個GameObject名為InventorySystem,現在已經不需要了,所以請把它刪除吧。

並將InventorySystem.cs拉進Knapsack Panel中。

接著新增Slot.cs以及ItemUI.cs,其中Slot.cs的作用為建立Item物件,ItemUI.cs的作用則為更新Item的Sprite以及數量,至於道具要新增到哪個Slot則由InventorySystem.cs統一管理。以下提供完整程式碼:

Slot.cs:

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

namespace RPG.Inventory{
 public class Slot : MonoBehaviour {

  [SerializeField] GameObject itemPrefab;

  public void StoreItem(Item item){
   // 若Slot底下沒有Item,則Instantiate一個
   if (transform.childCount == 0) {
    GameObject itemObject = Instantiate (itemPrefab, transform);
    itemObject.GetComponentInChildren ().SetItem (item);
   } else {
    // 已存在該Item,所以增加數量即可
    transform.GetComponentInChildren ().AddAmount ();
   }
  }

  public int GetItemID(){
   return transform.GetComponentInChildren ().Item.ID;
  }

  public bool IsFilled(){
   ItemUI itemUI = transform.GetComponentInChildren ();
   return itemUI.Amount >= itemUI.Item.Capacity;
  }
 }
}

ItemUI.cs:

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

namespace RPG.Inventory{
 public class ItemUI : MonoBehaviour{
  public Item Item { get; set; }
  public int Amount { get; set; }

  public void SetItem(Item item, int amount = 1){
   this.Item = item;
   this.Amount = amount;
   GetComponentInChildren ().sprite = Resources.Load (item.Sprite);
   GetComponentInChildren ().text = Amount.ToString();
  }

  public void AddAmount(int amount = 1){
   this.Amount += amount;
   GetComponentInChildren ().text = Amount.ToString();
  }
 }
}

InventorySystem.cs:

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

namespace RPG.Inventory{
 public class InventorySystem : MonoBehaviour {

  ItemList itemList;
  private Slot[] slotList;

  void Start () {
   ParseItemsJson ();

   slotList = GetComponentsInChildren ();
   // 測試程式碼,手動生成物品
   StoreItem (1);
   StoreItem (2);
   StoreItem (1);
  }

  public bool StoreItem(int id){
   Item item = GetItemByID (id);
   return StoreItem (item);
  }

  public bool StoreItem(Item item){
   if (item == null) {
    return false;
   }

   // 若物品的儲存容量為1,則將該物品直接放進空的Slot
   if (item.Capacity == 1) {
    return StoreItemInEmptySlot (item);
   }
   // 將相同的Item放在同一個Slot
   return StoreItemInSameSlot(item);
  }

  private bool StoreItemInSameSlot(Item item){
   foreach (Slot slot in slotList) {
    if (slot.transform.childCount >= 1 &&
     slot.GetItemID () == item.ID &&
     slot.IsFilled () == false) {
     // 將新Item與同一個Item放在一起
     slot.StoreItem (item);
     return true;
    } 
   }
   // 若背包內不存在相同的Item,則放進空的Slot
   return StoreItemInEmptySlot (item);
  }

  private bool StoreItemInEmptySlot(Item item){
   foreach (Slot slot in slotList) {
    if (slot.transform.childCount == 0) {
     // 將Item存進該Slot
     slot.StoreItem (item);
     return true;
    }
   }
   Debug.LogError ("No Empty Slot.");
   return false;
  }

  private Item GetItemByID(int id){
   foreach (Item entity in itemList.ItemEntityList) {
    if (entity.ID == id) {
     return entity;
    }      
   }
   return null;
  }

  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);
   }
  }
 }
}


接著,請在Slot裡面放入Slot.cs,並將已經建立好Prefab的Item拉進參數Item Prefab。

在Item中則需要拉進ItemUI.cs。

最後執行遊戲測試看看吧!場景中成功出現兩個血量瓶和一個能量瓶了!

留言