クラフトベンチ
CoddyのUnityジャーニー「Unityにおけるゲームアーキテクチャ」セクションの一部。レッスン 49/50。
サバイバルゲームでは、クラフトベンチを使うと、集めたものを使えるアイテムに変えられます。2つのボタンで木と石を集め、3つのレシピでさらにアイテムを作ります。木2つで板材1つ、板材1つと石2つで斧1つ、板材4つでいかだ1つを作れます。レシピのボタンは、インベントリにレシピで必要なものがすべて揃っているときだけ押せます。クラフトすると、その材料は消費されます。レシピはベンチのInspectorで設定するデータなので、新しいレシピを追加するのにコードを変更する必要はありません。インベントリに変更があると、変更を監視しているすべての相手に通知され、変更のたびにJSONとして保存されるため、ゲームを終了しても何も失われません。
2つのスクリプトを作成します。Backpackに付けるInventoryと、Benchに付けるCraftingBenchです。
チャレンジ
難しいInventory:
public string itemとpublic int countを持つ[System.Serializable]クラスItemStack、およびpublic List<ItemStack> stacksを持つ[System.Serializable]クラスInventoryData。インベントリは1つのInventoryDataを保持します。public event Action Changed。変更のたびに発生します。public int Count(string item):そのアイテムをいくつ持っているかを返します。持っていない場合は0です。public void Add(string item, int amount)はアイテムのスタックに追加するか、リストの末尾に新しいスタックを追加します。public void Remove(string item, int amount)はスタックから取り除き、0になったスタックはリストから削除されます。public string Describe()はスタックを順番にWood 3, Plank 1のように並べて返すか、emptyを返します。- 変更のたびに、
Application.persistentDataPathにあるinventory.jsonに、InventoryDataのJsonUtility.ToJsonとしてすぐに保存されます。Awakeはファイルが存在する場合に読み込みます。
Inspectorで inventory、recipes、recipeButtons(レシピごとに1つ、同じ順序)、woodButton、stoneButton、inventoryText を設定する CraftingBench:
public string itemとpublic int amountを持つ[System.Serializable]クラスIngredient、およびpublic string resultとpublic List<Ingredient> needsを持つ[System.Serializable]クラスRecipe。ベンチのrecipesはList<Recipe>で、シーン内で設定します。- 素材を集めるボタンは
WoodまたはStoneを1つ追加します。各レシピボタンは、そのレシピのインデックスを使ってpublic void Craft(int index)を呼び出します。 - レシピに必要なものがインベントリに不足している場合、
Craftは何もしません。それ以外の場合は、すべての材料を取り除き、完成品を1つ追加して、Crafted Axeのようにログに出力します。 - 開始時およびインベントリが変更されるたびに、各レシピボタンはそのレシピを作成できる場合にのみクリック可能になります。また、
inventoryTextには Inventory という語の後に説明が表示され、Inventory: Wood 3, Plank 1またはInventory: emptyのようになります。
Play を押して、素材を集めていかだを作り、Stop を押してからもう一度 Play を押し、その後 Check を押してください。
自分で試してみよう
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
public class CraftingBench : MonoBehaviour
{
[SerializeField] private Inventory inventory;
[SerializeField] private Button[] recipeButtons;
[SerializeField] private Button woodButton;
[SerializeField] private Button stoneButton;
[SerializeField] private TMP_Text inventoryText;
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。