見出し画像

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

前回の記事はこちら
前回は階段メニューを表示できるようにしました。

「上る」、「下りる」を選んだらマップを読み込み直す

まずはプレイヤーの位置は考えず、マップを読み込み直す所からコードを書いていきたいと思います。
LoadFieldMapクラスに新しいメソッドを加えて、Startメソッドを変更します。

// メソッドを追加
/**
* マップを読み込む
*/
public void Load()
{
   field.Reset();
   Array2D mapdata = ReadMapFile(mapName);
   if (mapdata != null)
   {
       field.Create(mapdata);
   }
}

// メソッドを変更
void Start()
{
   Load();
}

StairsMenuActionクラスに新しいパラメーターとメソッドを加えて、ActEndメソッドを変更します。

// パラメーターを追加
public LoadFieldMap loadFieldMap;

// メソッドを追加
/**
* 階を変更
*/
private void ChangeFloor()
{
   loadFieldMap.Load();
}

// メソッドを変更
private void ActEnd()
{
   string method = subMenu.GetSelectItemMethod();
   if (!method.Equals("Remain")) ChangeFloor();
   action = EAct.TurnEnd;
}

テストしてみます。「上る」を選んだときも「下りる」を選んだときも下り階段(スタート地点)に戻り、敵もアイテムもリセットされていればOKです。

選択肢によってプレイヤーの開始地点を変える

「上る」を選んだときは下り階段の方に、「下りる」を選んだときは上り階段の方にプレイヤーを移動します。
Fieldクラスに新しいパラメーターを追加し、SetObjectメソッドを変更して下さい。

// パラメーターを追加
public string startStairs = "Down";

// メソッドを変更
public void SetObject(string name, string type, int xgrid, int zgrid)
{
   switch (type)
   {
       case "Stairs":
           if (name.Contains("Down"))
               stairs.GetComponentsInChildren<ObjectPosition>()[1].SetPosition(xgrid, zgrid);
           else
               stairs.GetComponentsInChildren<ObjectPosition>()[0].SetPosition(xgrid, zgrid);
           if (name.Contains(startStairs)) playerMovement.SetPosition(xgrid, zgrid);
           break;
       case "Enemy":
           /*   省略   */
           break;
       case "Item":
           /*   省略   */
           break;
   }
}

次にStairsMenuActionスクリプトを開いて、ChangeFloorとActEndメソッドを変更しましょう。

private void ChangeFloor(string stairs)
{
   if (stairs.Contains("Down")) stairs = "Up";
   else stairs = "Down";
   field.startStairs = stairs;
   loadFieldMap.Load();
}

private void ActEnd()
{
   string method = subMenu.GetSelectItemMethod();
   if (!method.Equals("Remain")) ChangeFloor(method);
   action = EAct.TurnEnd;
}

テストしてみます。「下りる」を選んだら上り階段の方に、「上る」を選んだら下り階段の方にプレイヤーが移動したと思います。

階数を表すパラメーター

階段を上ったり下りたりしたとき、通常は階数が増減します。それを実装するために、まずはFieldクラスに階数を表すパラメーターを追加したいと思います。

public static int floorNum = 1;

どこからでも参照できるように、静的なパラメーターにしました。

階数を増減する

階を移動すると、階数を増減するようにします。
StairsMenuActionクラスのChangeFloorメソッドを変更します。

private void ChangeFloor(string stairs)
{
   if (stairs.Contains("Down"))
   {
       stairs = "Up";
       Field.floorNum--;
   }
   else
   {
       stairs = "Down";
       Field.floorNum++;
   }
   field.startStairs = stairs;
   loadFieldMap.Load();
}

フェードイン・アウトを実装する

さて、今のままでは何も演出がないので階層を移動した感じがありません。という訳で画面を黒にフェードさせることで、雰囲気を出そうと思います。
まずはヒエラルキータブのCanvas階層下に黒いパネルを用意し、名前を「FadePanel」にします。

スクリーンショット 2020-05-31 16.10.50

そして新しいスクリプト、「FadeInOut」を作成し、以下のように記述します。

using UnityEngine;
using UnityEngine.UI;

public class FadeInOut : MonoBehaviour
{
   public float maxPerFrame = 0.0005f;
   private float complementFrame;
   private bool isFadeOut = false;
   private Image image;

   // Start is called before the first frame update
   void Start()
   {
       complementFrame = maxPerFrame / Time.deltaTime;
       image = GetComponent<Image>();
   }

   // Update is called once per frame
   void Update()
   {
       if (!isFadeOut && image.color.a <= 0) return;
       if (isFadeOut && image.color.a >= 1.0f) return;
       if (isFadeOut) FadeOut();
       if (!isFadeOut) FadeIn();
   }

   /**
   * フェードさせる
   */
   public bool Fade(bool isFadeOut)
   {
       if (!isFadeOut && image.color.a <= 0) return true;
       if (isFadeOut && image.color.a >= 1.0f) return true;
       this.isFadeOut = isFadeOut;
       return false;
   }

   /**
   * フェードアウト
   */
   private void FadeOut()
   {
       float alpha = image.color.a + complementFrame;
       if (alpha > 1.0f) alpha = 1.0f;
       image.color = new Color(image.color.r, image.color.g, image.color.b, alpha);
   }

   /**
   * フェードイン
   */
   private void FadeIn()
   {
       float alpha = image.color.a - complementFrame;
       if (alpha < 0) alpha = 0;
       image.color = new Color(image.color.r, image.color.g, image.color.b, alpha);
   }
}

パネルの色の透明度を増減してフェードイン・アウトを実装しました。
ビルドしたら、FadePanelにアタッチしておきます。
テストしてみましょう。プレイボタンを押すと以下のようにフェードインのような演出がされたはずです。

フェードアウト

階を移動した時の演出

それでは階を移動した時にフェードする処理を書いていきます。ついでに、画面が暗くなった時に現在の階数も表示したいと思います。
まず、FadePanel階層下にテキストを作成します。そして以下のように設定して下さい。

スクリーンショット 2020-05-31 17.51.37

フォントサイズの調節が終わったら、テキストは空にしておいて下さい。
そしてFadeInOutクラスを変更します。

// パラメーターを追加
public Text text;

// メソッドを変更
public bool Fade(bool isFadeOut, string str = "")
{
   if (!isFadeOut && image.color.a <= 0) return true;
   if (isFadeOut && image.color.a >= 1.0f) return true;
   if (this.isFadeOut != isFadeOut)
   {
       this.isFadeOut = isFadeOut;
       text.text = str;
   }
   return false;
}

準備が整ったので、StairsMenuActionスクリプトを開きましょう。
以下のように変更します。

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

// メソッドを変更
private void SelectSubMenuItem()
{
   if (Input.anyKeyDown && Input.GetKeyDown(KeyCode.Space))
   {
       Hide();
       string method = subMenu.GetSelectItemMethod();
       if (method.Equals("Remain")) action = EAct.ActEnd;
       else
       {
           string str = (Field.floorNum + (method.Contains("Down") ? -1 : 1)) + "F";
           fade.Fade(true, str);
           action = EAct.Act;
       }
   }
}

private void Act()
{
   if (fade.Fade(true))
   {
       if (Input.anyKeyDown && Input.GetKeyDown(KeyCode.Space))
       {
           string method = subMenu.GetSelectItemMethod();
           ChangeFloor(method);
           fade.Fade(false);
           action = EAct.ActEnd;
       }
   }
}

private void ActEnd()
{
   if (Input.GetKeyUp(KeyCode.Space)) action = EAct.TurnEnd;
}

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

テストしてみます。
「残る」以外を選んだ時にフェードアウトし、スペースキーが再度入力されたらフェードインを開始します。フェードが終わるまで移動や攻撃はできません。

階移動の演出

これで一応階移動の基本はできました。
次回は2階のマップを作成し、読み込もうと思います。

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