【Unity2d】イベントでメッセージを呼び出そう

Unity2D

Unity2D ARPG

当ブログの毎日更新は停止しましたが、更新しないとは言っていません(笑)

ってことでゲームつくりの続きになります。

前回はメッセージ処理を作ったので、今度はイベントを調べたときにメッセージが出るようにしてみましょう。

手順としてはウィンドウは非表示状態にしておき、文章は空にしておきます。

そしてイベントを調べたらメッセージイベントが取得できるのでその判定でウィンドウを開き、
イベントの内容から表示するテキストをコピーしてきて描写するという流れになります。

ウィンドウを非表示にしておく

Unityではゲーム開始前に非表示にするとオブジェクトの取得ができなかったはずなので、
エディタ側の非表示をするのではなくアルファ値で透明を利用しての非表示を利用します。

まずはウィンドウの状態を管理するためにステータスマネージャーでシステム系の値を管理する変数を作りましょう。

State_Managerのクラス変数に作ります。

  // システムステータス
  public static List<float> _systemStatus = new List<float>());
  public List<float> getSystemStatus
  {
    get
    {
      return State_Manager._systemStatus;
    }
  }

リスト型のsetの作り方ががいまいちわからなかったのでpublicにして書き込み関数を作ります。

判明次第書き換えます。

  // システム状態を書き換える
  public void setSystemStatus(float num, int itemNo)
  {
    State_Manager._systemStatus[itemNo] = num;
  }

これでウィンドウの状態を操作できるようになったので、ウィンドウにステータスを持たせるスクリプトを付けます。

システム関連は同じスクリプトを持たせ、タグによって使う関数を分けておけば1つのスクリプトに処理をまとめられそうです。

といってもやることはステータスを監視してその状態を適用するだけのスクリプトになります。

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

public class _ObjectStateSystem : MonoBehaviour
{

  // オブジェクトタイプ
  [SerializeField]
  private string systemObjectType = "";

  // ウィンドウの可視状態
  private bool _windowVisible = false;
  // ウィンドウの透明度
  private float _windowAlpha = 1f;

  // ウィンドウのカラー
  private Vector3 _windowColor = new Vector3();

  // ステータスオブジェクト
  private State_Player _State;
  // 自身
  private SpriteRenderer _SelfSprite;

  void Start()
  {
    _State = GameObject.FindGameObjectsWithTag("State_Manager")[0].GetComponent<State_Player>();
    _SelfSprite = this.GetComponent<SpriteRenderer>();


  }
  void Update()
  {
    switch (systemObjectType)
    {
      case "window":
        _windowUpdate();
        break;
      default:
        break;
    }


  }

  // ウィンドウ
  private void _windowUpdate()
  {
    // ウィンドウの可視を監視
    if (_State.getSystemStatus[0] <= 0f)
    {
      _windowVisible = false;
    }
    else
    {
      _windowVisible = true;
    }


    // ウィンドウの透明度を監視
    if (_windowAlpha != _State.getSystemStatus[1])
    {
      _windowAlpha = _State.getSystemStatus[1];
      _SelfSprite.color = new Color(_SelfSprite.color.r, _SelfSprite.color.g, _SelfSprite.color.b, _windowAlpha);
    }

  }

}

ウィンドウに取り付けてインスペクタでwindowという名前にします。

そうするとupdateではswitchで振り分けられたアップデート関数だけが動くという仕組みです。

こうすれば1つのスクリプトでシステム系の管理がまとまります。

カラーもアルファの値もfloatの0.0f ~ 1.0fの範囲になりますので注意しましょう。

これでウィンドウの表示を一旦操作することができるようになったので、
ゲーム開始時にウィンドウを透明にして文字列をなしにしておきましょう。

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

public class _ObjectStateSystem : MonoBehaviour
{

  // オブジェクトタイプ
  [SerializeField]
  private string systemObjectType = "";

  // ウィンドウの可視状態
  private bool _windowVisible = false;
  // ウィンドウの透明度
  private float _windowAlpha = 0f;

  // ウィンドウのカラー
  private Vector3 _windowColor = new Vector3();

  // ステータスオブジェクト
  private State_Player _State;
  // 自身
  private SpriteRenderer _SelfSprite;
  private Text _SelfText;

  void Start()
  {
    _State = GameObject.FindGameObjectsWithTag("State_Manager")[0].GetComponent<State_Player>();
    _SelfSprite = this.GetComponent<SpriteRenderer>();
    _SelfText = this.GetComponentInChildren<Text>();
    _SelfText.text = "";

  }
  void Update()
  {
    switch (systemObjectType)
    {
      case "window":
        _windowUpdate();
        break;
      default:
        break;
    }


  }

  // ウィンドウ
  private void _windowUpdate()
  {
    // ウィンドウの可視を監視
    if (_State.getSystemStatus[0] <= 0f)
    {
      _windowVisible = false;
    }
    else
    {
      _windowVisible = true;
    }


    // ウィンドウの透明度を監視
    if (_windowAlpha != _State.getSystemStatus[1])
    {
      _windowAlpha = _State.getSystemStatus[1];
      _SelfSprite.color = new Color(_SelfSprite.color.r, _SelfSprite.color.g, _SelfSprite.color.b, _windowAlpha);
    }

  }

}

ウィンドウのアルファを0にしておきましょう。

これでゲーム開始時は透明になってくれます。

おそらく数フレーム間は描写されたままになるので、ゲーム開始時は暗転している状態から始めるのが理想でしょう。

あとはイベントを調べたらウィンドウのアルファを1fにすれば描写されます。

ハンマーオブジェクトを調べてメッセージを描写する

早速イベントで処理してみましょう。

イベントを調べたら「"5,0,0"」という文字列を取得できていましたね。

それを利用して描写します。

EventManagerを変更しましょう。

  // イベントを監視して執行
  private void EventExecutioner()
  {

    // イベントが1つでもあったら処理をする
    if (_State.getEventQueue.Count != 0)
    {
      // 1.イベントキュー取り出し(大元キューの0個目を削除)
      // 2. 取り出したイベントをint型配列に変換
      int[] ev = _str2IntArray(_State.getEventData());

      // 配列1つ目を元に処理を分岐
      switch (ev[0])
      {
        // メッセージイベント
        case 5:
          _State.setSystemStatus(1f, 1);
          break;
        case 0:
          break;
      }
    }
  }

これでイベントを調べたときにウィンドウが出ます。

あとはイベントの2つ目をもとにメッセージを描写させましょう。

本来はデータベースを作成したほうがいいのですが、体験版ではそこまでメッセージは多くないので
一旦テキストはプログラムに埋め込んで簡単に扱えるようにしておきましょう。

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

public class Message_db : MonoBehaviour
{
  private static List<string> _message = new List<string> {
    // 0個目はダミーメッセージ
    "ダミーです",
    "ハンマーが壁に掛けられている",
    "取りますか?",
  };

  public List<string> Message
  {
    get
    {
      return Message_db._message;
    }
  }
}

こんな感じにDB用のスクリプトを作ってここから引っ張ってきます。

あとはオブジェクトに引っ付けて取得すればメッセージの取得をできます。

書き換えができないようにprivateにしておいてゲッターでとるようにしましょう。

これをもとにウィンドウにメッセージを表示してみましょう。

  // イベントを監視して執行
  private void EventExecutioner()
  {

    // イベントが1つでもあったら処理をする
    if (_State.getEventQueue.Count != 0)
    {
      // 1.イベントキュー取り出し(大元キューの0個目を削除)
      // 2. 取り出したイベントをint型配列に変換
      int[] ev = _str2IntArray(_State.getEventData());

      // 配列1つ目を元に処理を分岐
      switch (ev[0])
      {
        // メッセージイベント
        case 5:
          // ウィンドウを開く
          _State.setSystemStatus(1f, 1);
          // メッセージを更新
          _State.setSystemStatus(ev[1], 5);
          break;
        case 0:
          break;
      }
    }
  }

これで文章の更新ができますね。

_ObjectStateSystem.csはこんな感じです。

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

public class _ObjectStateSystem : MonoBehaviour
{

  // オブジェクトタイプ
  [SerializeField]
  private string systemObjectType = "";

  // ウィンドウの可視状態
  private bool _windowVisible = false;
  // ウィンドウの透明度
  private float _windowAlpha = 0f;

  // ウィンドウカラーR
  private float _windowRed = 0f;
  // ウィンドウカラーG
  private float _windowGreen = 0f;
  // ウィンドウカラーB
  private float _windowBlue = 0f;

  // メッセージ
  private float _message = 0f;

  // ウィンドウのカラー
  private Vector3 _windowColor = new Vector3();

  // 

  // ステータスオブジェクト
  private State_Player _State;
  // 自身
  private SpriteRenderer _SelfSprite;
  private Text _SelfText;

  // メッセージDBオブジェクト
  private Message_db msgDB;

  void Start()
  {

    _State = GameObject.FindGameObjectsWithTag("State_Manager")[0].GetComponent<State_Player>();
    _SelfSprite = this.GetComponent<SpriteRenderer>();
    _SelfText = this.GetComponentInChildren<Text>();
    _SelfText.text = "";

    // メッセージDB取得
    msgDB = GameObject.FindGameObjectsWithTag("MSGDB")[0].GetComponent<Message_db>();

  }
  void Update()
  {
    switch (systemObjectType)
    {
      case "window":
        _windowUpdate();
        break;
      default:
        break;
    }


  }

  // ウィンドウ
  private void _windowUpdate()
  {
    // ウィンドウの可視を監視
    if (_State.getSystemStatus[0] <= 0f)
    {
      _windowVisible = false;
    }
    else
    {
      _windowVisible = true;
    }


    // ウィンドウの透明度を監視
    if (_windowAlpha != _State.getSystemStatus[1])
    {
      _windowAlpha = _State.getSystemStatus[1];
      _SelfSprite.color = new Color(_SelfSprite.color.r, _SelfSprite.color.g, _SelfSprite.color.b, _windowAlpha);
    }

    // メッセージを更新
    if (_message != _State.getSystemStatus[5])
    {
      _message = _State.getSystemStatus[5];
      _SelfText.text = msgDB.Message[(int)_message];
    }

  }

}

数値をfloatで管理していますが、配列の添え字はint型でないといけないのでキャストしています。

Unity2D メッセージ

こんな感じですね。

もし表示されな人はソーティングレイヤーを見直してみてください。

2DはZ軸での調整ではなくソーティングレイヤーでの重なりの調整がおすすめだそうです。

それでは!