見出し画像

【Unity】3Dローグライクゲームの作り方〜Step14-9〜

前回の記事はこちら
前回は倉庫インベントリのソート機能実装などを行いました。

コインを預けたり引き出せるようにする

今回はコインを預けたり、引き出せるようにするところからコードを書いていきたいと思います。
WareHouseMoneyActionクラスを変更して下さい。

// メソッドを追加
/**
* コインを預け出しする
*/
private void DepositAndWithdraw()
{
   int wareHouseMoney = wareHouseAction.itemInventory.money;
   int playerMoney = wareHouseAction.playerInventoryAction.itemInventory.money;
   int wMoney = open > 0 ? playerMoney : wareHouseMoney;
   OutputMoney(wareHouseMoney, playerMoney);
   if (Input.anyKeyDown) inputTime = 0;
   if (KeyConfig.GetKeyDown(KeyConfig.EType.WAREHOUSEMOVELEFT))
       money = Mathf.Max(0, money - 10);
   if (KeyConfig.GetKeyDown(KeyConfig.EType.WAREHOUSEMOVERIGHT))
       money = Mathf.Min(wMoney, money + 10);
   if (KeyConfig.GetKeyDown(KeyConfig.EType.WAREHOUSEMOVEUP))
       money = Mathf.Max(0, money - 1);
   if (KeyConfig.GetKeyDown(KeyConfig.EType.WAREHOUSEMOVEDOWN))
       money = Mathf.Min(wMoney, money + 1);
   inputTime += Time.deltaTime;
   if (inputTime < inputHoldDelay) return;
   if (!Input.anyKey) return;
   inputTime = 0;
   if (KeyConfig.GetKey(KeyConfig.EType.WAREHOUSEMOVELEFT))
       money = Mathf.Max(0, money - 100);
   if (KeyConfig.GetKey(KeyConfig.EType.WAREHOUSEMOVERIGHT))
       money = Mathf.Min(wMoney, money + 100);
   if (KeyConfig.GetKey(KeyConfig.EType.WAREHOUSEMOVEUP))
       money = Mathf.Max(0, money - 10);
   if (KeyConfig.GetKey(KeyConfig.EType.WAREHOUSEMOVEDOWN))
       money = Mathf.Min(wMoney, money + 10);
}

/**
* コイン枚数の表示の更新
*/
private void OutputMoney(int wareHouseMoney, int playerMoney)
{
   wareHouseMoney += money * open;
   playerMoney -= money * open;
   addText1.text = addText2.text = money + "";
   wareHouseMoneyText.text = wareHouseMoney + "";
   playerMoneyText.text = playerMoney + "";
}

// メソッドを変更
private void ActBegin()
{
   DepositAndWithdraw();
   KeyInput();
}

private void MoveEnd()
{
   if (Mathf.Abs(open) > 0) action = EAct.ActBegin;
   else
   {
       wareHouseAction.itemInventory.money = int.Parse(wareHouseMoneyText.text);
       wareHouseAction.playerInventoryAction.itemInventory.money = int.Parse(playerMoneyText.text);
       depositWindow.SetActive(false);
       withdrawWindow.SetActive(false);
       gameObject.SetActive(false);
       money = 0;
       action = EAct.TurnEnd;
   }
}

実行してみます。

スクリーンショット 2020-11-13 22.15.54

コインを預ける画面

スクリーンショット 2020-11-13 22.16.07

上記の状態でコイン引き出しの画面を開いた

マイナスの値にならず、かつ引き出し側のコイン以上に引き出されないか確認しておきましょう。
これで倉庫の機能は全て実装できました。

宿泊と倉庫利用の切り替え

さて、そろそろ拠点内のセーブを実装しないと(筆者が)忘れそうなので実装します。
なお、拠点内のセーブは宿屋に泊まることと同義とします。
ということは、宿屋の場所でアクションキーを押した時に宿に泊まるのか倉庫を利用するのか選べないといけませんね。という訳で宿屋用のスクリプトを別に用意します。
ですがその前に宿屋用の選択肢(SubMenu)を用意します。
ヒエラルキータブはこんな感じです。

スクリーンショット 2020-11-13 23.05.54

SubMenu自体はInventoryWindowなどから持ってくると楽です。
SubMenuコンポーネントを以下のようにして下さい。

スクリーンショット 2020-11-13 23.25.30

Choice Namesは自由に設定しましょう。
それができたら「InnAction」スクリプトを作成し、以下を記述します。

using UnityEngine;

public class InnAction : MonoBehaviour
{
   public SubMenu subMenu;
   public WareHouseAction wareHouseAction;
   public float inputHoldDelay = 0.3f;

   private EAct action = EAct.KeyInput;
   private string choiceOrder = "Save,WareHouse";
   private float inputTime = 0;

   // 独自の更新メソッド
   public void Proc(bool isAction = false)
   {
       switch (action)
       {
           case EAct.KeyInput: KeyInput(isAction); break;
           case EAct.ActBegin: ActBegin(); break;
           case EAct.Act: Act(); break;
           case EAct.ActEnd: ActEnd(); break;
           case EAct.TurnEnd: TurnEnd(); break;
       }
   }

   /**
   * 現在の行動状態を返す
   */
   public EAct GetAction() => action;

   /**
   * 選択するサブメニューの項目を変更する
   */
   private bool MoveSelectSubMenuItem()
   {
       if (Input.anyKeyDown) inputTime = 0;
       if (KeyConfig.GetKeyDown(KeyConfig.EType.INNMENUUP))
           return subMenu.MoveSelect(EDir.Up);
       if (KeyConfig.GetKeyDown(KeyConfig.EType.INNMENUDOWN))
           return subMenu.MoveSelect(EDir.Down);
       inputTime += Time.deltaTime;
       if (inputTime < inputHoldDelay) return true;
       if (!Input.anyKey) return true;
       inputTime = 0;
       if (KeyConfig.GetKey(KeyConfig.EType.INNMENUUP))
           return subMenu.MoveSelect(EDir.Up);
       if (KeyConfig.GetKey(KeyConfig.EType.INNMENUDOWN))
           return subMenu.MoveSelect(EDir.Down);
       return true;
   }

   /**
   * サブメニューの項目を選択
   */
   private void SelectSubMenuItem()
   {
       if (KeyConfig.GetKeyDown(KeyConfig.EType.INNMENUACTION))
       {
           Hide();
           string method = subMenu.GetSelectItemMethod();
           action = EAct.Act;
       }
   }

   /**
   * メニューを開く
   */
   private void Show()
   {
       subMenu.SetChoices(choiceOrder);
       subMenu.Show();
       gameObject.SetActive(true);
       action = EAct.ActBegin;
   }

   /**
   * メニューを閉じる
   */
   private void Hide()
   {
       gameObject.SetActive(false);
   }

   /**
   * 待機中
   */
   private void KeyInput(bool isAction)
   {
       if (isAction) Show();
   }

   /**
   * アクションを始める
   */
   private void ActBegin()
   {
       MoveSelectSubMenuItem();
       SelectSubMenuItem();
       if (KeyConfig.GetKeyDown(KeyConfig.EType.INNMENUCLOSE))
       {
           Hide();
           action = EAct.TurnEnd;
       }
   }

   /**
   * アクション中
   */
   private void Act()
   {
       string method = subMenu.GetSelectItemMethod();
       if (method.Equals("WareHouse"))
       {
           wareHouseAction.Proc(true);
       }
       action = EAct.TurnEnd;
   }

   /**
   * アクションが終わった
   */
   private void ActEnd()
   {
       action = EAct.TurnEnd;
   }

   /**
   * ターンが終わった
   */
   private void TurnEnd()
   {
       action = EAct.KeyInput;
   }
}

これはInnMenuWindowにあたるオブジェクトにアタッチしておきます。
KeyConfigクラスのETypeに追記します。

// 宿屋メニュー操作
INNMENUUP = KeyCode.UpArrow,
INNMENUDOWN = KeyCode.DownArrow,
INNMENUACTION = KeyCode.Space,
INNMENUCLOSE = KeyCode.Escape,​

SequenceManagerInTownクラスを変更します。

// パラメーターを追加
public InnAction innAction;

private void Update()
{
   EAct act = inventoryAction.GetAction();
   if (act != EAct.KeyInput)
   {
       inventoryAction.Proc();
       return;
   }
   act = shopAction.GetAction();
   if (act != EAct.KeyInput)
   {
       shopAction.Proc();
       return;
   }
   act = wareHouseAction.GetAction();
   if (act != EAct.KeyInput)
   {
       wareHouseAction.Proc();
       return;
   }
   act = innAction.GetAction();
   if (act != EAct.KeyInput)
   {
       innAction.Proc();
       return;
   }
   if (KeyConfig.GetKeyDown(KeyConfig.EType.FACILITYACTION))
   {
       switch (playerMovement.facility)
       {
           case "Shop":
               shopAction.Proc(true);
               return;
           case "Inn":
               innAction.Proc(true);
               return;
       }
   }
   inventoryAction.Proc();
   act = inventoryAction.GetAction();
   if (act != EAct.KeyInput) return;
   playerMovement.Move();
}

実行してみます。宿屋の前でアクションキーを押すと選択肢が現れます。
倉庫の方を選ぶと倉庫画面が出てきて、宿屋の方は何もせず閉じます。

スクリーンショット 2020-11-14 2.51.40

宿屋を選択するとフェードする

宿泊した感じを少しでも出す為に、フェードをかけたいと思います。
まずはフェードパネルを用意します。これは他のシーンからコピーして持ってきましょう。
そしてInnActionスクリプトを以下のように変更します。

// パラメーターを追記
public FadeInOut fade;

// メソッドを変更
private void Act()
{
   string method = subMenu.GetSelectItemMethod();
   switch (method)
   {
       case "Save":
           if (fade.Fade(true)) action = EAct.ActEnd;
           break;
       case "WareHouse":
           wareHouseAction.Proc(true);
           action = EAct.TurnEnd;
           break;
   }
}

private void ActEnd()
{
   if (fade.Fade(false)) action = EAct.TurnEnd;
}

実行してみます。宿屋を選ぶとフェードアウトし、その後すぐにフェードインすればOKです。

という訳で短いですが今回はここまでです。
次回は実際に拠点セーブできるようにしたいです。


この記事が気に入ったらサポートをしてみませんか?