【Unity】RPGを作るチュートリアルその93 触れた時にイベントを起動する仕組み

【Unity】RPGを作るチュートリアルその93 触れた時にイベントを起動する仕組み

シンプルなRPGをUnityで作るチュートリアルシリーズの93回目です。

第92回ではカウンターなどの特定のタイル越しにイベントを起動する機能を実装しました。

今回は操作キャラクターが触れた時にイベントを起動する仕組みを実装します。

 

 

制作環境

MacBook Pro 2023 Apple M2 Max

Unity6 (6000.0.30f1) Silicon

 

作業内容と順序

シンプルなRPGを作る上でどんな作業が必要か、どんな順番で作っていくと良さそうか、別ページで検討しました。基本的にこの流れに沿って進めていきます。

 

チュートリアルの一覧

このシリーズ全体の一覧は以下のページにまとめています。

 

前回の内容

前回はカウンターなどの特定のタイル越しにイベントを起動する機能を実装しました。

 

タイルに触れた時にイベントを起動

イベントを起動する方法としては、Enumで定義した以下の5通りを考えています。

  • なし
  • 決定ボタン
  • タイルに乗った時
  • マップに入った時に自動で実行
  • システム側で起動

このうち決定ボタンによる起動は実装済みなので、今回はタイルに乗った時に起動する仕組みを実装していきたいと思います。この種類のイベントは、操作キャラクターが移動完了したタイミングで、そのタイルにイベントが配置されているか確認し、もしあればイベントを実行します。

操作キャラクターの移動後には「PlayerMover」のクラスでPostMove()が呼ばれるので、このタイミングでイベントの有無を確認します。確認処理は「PlayerEventChecker」の方に実装します。

また、触れた時に実行したいイベントとしてはマップ移動のイベントがあります。そのため、このイベントについても作成していきたいと思います。

 

既存のクラスの変更

上記の動きを実現するため、以下のクラスを変更していきます。

  • PlayerEventChecker
  • PlayerMover

 

PlayerEventCheckerの変更

イベントの確認を行うクラスでは既に決定ボタンを押した際の動作を実装しています。これに加えて、タイル上のイベントについても確認するようにします。

既存のGetGameObjectFromRaycastHits()のメソッドの後ろにGetGameObjectFromColliders()のメソッドを追加します。これは移動後のタイルで操作キャラクターと重なっているColliderの中から先頭のものを取得します。

 

続いて、既存のSetEventMoverDirectionPrevious()のメソッドの後ろにCheckOnTileEvent()のメソッドを追加します。これは移動後のタイルでイベントがあるかどうかを確認するメソッドで、「PlayerMover」のPostMove()のメソッドから呼ばれる想定です。

イベントのゲームオブジェクトについては、移動する際にぶつからないけどColliderは持つ、といった状態にして、ColliderのOverlap()メソッドを使ってコライダー同士が重なっていることを確認できるようにします。念の為、対象のイベントのTilemap上の位置と、操作キャラクターのTilemap上の位置が同じであることを確認の上、イベントを開始するようにしています。

イベントが開始した場合は戻り値でtrueを返すようにしていて、「PlayerMover」側でtrueを検知したら後続のエンカウント処理には進まないようにします。イベントの発生するマスでエンカウントすると制御が大変だったりするので、仕様としてエンカウントしないようにしておくのもひとつの方法かと思います。

 

PlayerMoverの変更

次に「PlayerMover」では、移動後に呼ばれるメソッドを変更していきます。

PostMove()のメソッドでは「_isCheckPostMove」のフラグで移動後の確認処理を行うかどうかを見ています。イベントプロセス側でキャラクターを移動させる際に別のイベントを呼んだりエンカウントしたりすると大変なので、そうした場合はfalseにして処理を行わないようにします。

エンカウント処理を行う前に、今いるマスにイベントがあるかどうかを確認します。もしイベントが開始したら戻り値としてtrueが返ってくるので、エンカウント処理を行わずに抜けます。

 

マップ切り替えのイベントプロセスを作成

タイルに触れた時にイベントを実行する仕組みを作ったので、実際にイベントプロセスも作成していきます。作りたいイベントはマップの切り替えで、村からフィールドに移動するようにしたいと思います。

NPCのゲームオブジェクトとは別にイベント専用のゲームオブジェクトを作成し、イベントの有無を検知するためのColliderを追加していきます。また、画像のないイベントになるので、編集中にイベントの位置を把握できるように仮置き画像を用意します。「EventGraphicController」を使うことによって、ゲームの実行中は透明な画像に切り替わるようにしたいと思います。

画像 概要
イベントの存在を知らせるスプライト イベントの存在を知らせる画像
透明な画像 実行時用の透明な画像(左端にいます)

 

Projectウィンドウから「Assets/Images/UI」のフォルダを開き、上の2つの画像をインポートします。

画像のインポート
画像のインポート

 

インポートした2つの画像を選択し、Inspectorウィンドウからタイル用画像のプリセットをダブルクリックして適用し、インポート設定の右下にある [Apply] をクリックします。

プリセットの適用
プリセットの適用

 

マップを切り替えるイベントプロセスのクラス

「EventProcessBase」を継承して、マップを切り替えるためのイベントプロセスを作成していきます。Projectウィンドウから「Assets/Scripts/Event/Process」のフォルダを開き、MonoBehaviourのスクリプトファイルを作成します。名前は [EventProcessMoveMap] にしました。

マップ移動のイベントプロセス
マップ移動のイベントプロセス

 

作成した「EventProcessMoveMap」の中身は以下のように記載しました。

Inspectorウィンドウから移動先のマップIDとTilemap上の座標を設定できるようにします。

Execute()のメソッドでは「MapManager」と「PlayerMover」への参照を取得した後、マップの切り替え処理と操作キャラクターの位置の変更処理を行なっています。どちらかの参照がない場合は切り替え処理を行わずにエラーメッセージを出力して次のイベントプロセスを呼ぶようにします。

 

スクリプトのアタッチ

マップ切り替え用のイベント向けにゲームオブジェクトを作成し、イベントプロセスのスクリプトをアタッチしましょう。

まずは編集のため、Projectウィンドウの「Assets/Prefabs/Map」のフォルダにある「Map_0001_Village」を「Grid」の子オブジェクトとしてインスタンス化します。ゴブリンのGameObjectも「Map_0001_Village」内の「NPC」に移動させます。全体を実装するタイミングでダンジョンに移動させる予定です。

マップのインスタンス化
マップのインスタンス化

 

「NPC_Goblin」を複製して「Events」の子オブジェクトとして移動させます。名前は [Event_MoveMap] にしました。

イベント用のゲームオブジェクト
イベント用のゲームオブジェクト

 

Inspectorウィンドウから、タグを [Untagged] に変更します。これは「NPC」のままだとこのタイルの上に移動できなくなるためです。

また、「Transform」にて「Position」の「X」を [7.5] に、「Y」を [-0.5] に変更します。村の入り口あたりに配置されるようにしています。

「SpriteRenderer」の「Sprite」は今回インポートした [event_indicator] の画像に変更します。

「Animator」と「NpcMover」のコンポーネントは、コンポーネント右上のメニューにある [Remove Component] から外しておきます。「Box Collider 2D」についてはそのまま使います。

イベント用ゲームオブジェクトの設定
イベント用ゲームオブジェクトの設定

 

「EventGraphicController」のゲームオブジェクトを選択し、Inspectorウィンドウから設定を行います。「Event Graphic Records」では要素を追加して、子オブジェクトの「EventGraphicRecord」をアサインします。「Sprite Renderer」では「Event_MoveMap」のものをアサインしましょう。

EventGraphicControllerの設定
EventGraphicControllerの設定

 

「EventGraphicRecord」のゲームオブジェクトを選択し、「Event Pages」に要素を追加して、マップ移動イベントの「EventPage」をアサインします。このイベントページでは条件を設定しないため、常に画像の切り替えが発生します。切り替える画像として「Sprite」の項目で [event_indicator_transparent] をアサインします。

EventGraphicRecordの設定
EventGraphicRecordの設定

 

続いてイベントプロセスの作成を行います。ゴブリンのゲームオブジェクトを複製したのでメッセージ表示のイベントプロセスが残っています。まずはこちらを削除してから、新しく空のゲームオブジェクトを作成します。名前は [MoveMap] にしました。

イベントプロセスの作成
イベントプロセスの作成

 

作成した「MoveMap」では、マップIDに [2] を、座標のXとYにそれぞれ [2][4] を設定します。移動先はフィールドに配置された村のタイルの1つ下です。

マップ移動の設定
マップ移動の設定

 

続いて「EventPage」のゲームオブジェクトを選択し、Inspectorウィンドウから「Event Trigger」を [OnTile] に、「Start Process」を [MoveMap] に設定します。

EventPageの設定
EventPageの設定

 

イベントプロセスの編集が完了したら、「Map_0001_Village」のゲームオブジェクトを選択し、Inspectorウィンドウの「Override」のプルダウンから [Apply All] をクリックします。これにより、マップ用Prefabがインスタンス化された時にもマップ移動イベントなどの設定が反映された状態になります。また、イベントのテンプレート用Prefabの方には影響なく設定変更できます。

Prefabへの反映
Prefabへの反映

 

マップ表示時に画像を切り替える機能

画像を切り替える処理自体は入れていましたが、それを呼び出す側がまだ実装されていないため、このタイミングで実装しておきたいと思います。

変更を行う対象は「MapManager」で、ShowMap()のメソッドで表示処理が終わった後にイベントのグラフィックを確認するようにします。また、今回は実装しませんが、同じタイミングで自動イベントについても確認と開始を行う想定でいます。

今回コルーチンを使うため、usingディレクティブで「using System.Collections;」を追加しました。

 

ShowMap()のメソッドでは処理の最後にCheckEvent()の呼び出しを追加します。

 

既存のGetMapNameFromId()のメソッドの後ろに上記のメソッドを追加します。

GetEventsInMap()ではマップのゲームオブジェクトの子オブジェクトの中から「EventFileData」がアタッチされたものを取得します。

CheckEvent()ではコルーチンのCheckEventProcess()を起動します。次回以降に実装する自動イベントの確認を行うにあたって、処理の待ち合わせをしたい部分があるのでコルーチンで実装しています。

CheckEventGraphic()のコルーチンでは、引数のイベントファイルに対してSetEventGraphic()を呼んでいきます。これによってマップ表示時に画像の切り替えが行われます。

 

動作確認

スクリプトを保存して動作確認を行なっていきます。シーン内の「Map_0001_Village」についてはPrefabに変更を適用後に非表示にしておきましょう。

ゲームを実行し、村の入り口まで進んでいき、イベントを配置したタイルに触れた時にフィールドに移動することを確認します。

村の外に出た
村の外に出た

 

イベントのグラフィックの切り替えは1フレームずれていることから、一瞬ピンク色のタイルが表示されることがあります。ゲームの全体の流れを作っていくタイミングで画面のフェードイン、フェードアウトを入れて、画像切り替えの瞬間が画面に表示されないようにします。

 

今回のブランチ

 

まとめ

今回は操作キャラクターが触れた時にイベントを起動する仕組みを実装しました。また、その起動方法を使ったイベントプロセスとしてマップの切り替え処理も実装しました。マップの切り替えのタイミングを通知するイベントはよく使うので、早めに実装しておくと色々と確認もしやすくなるかと思います。

次回はフェードイン、フェードアウトの機能を実装していきます。

 

     

ゲーム開発の攻略チャートを作りました!

CTA-IMAGE

「ゲームを作ってみたいけど、何から手を付けていいか分からない!」


そんなお悩みをお持ちの方向けに、todoがアプリをリリースした経験を中心に、ゲーム作りの手順や考慮すべき点をまとめたe-bookを作成しました。ゲーム作りはそれ自体がゲームのように楽しいプロセスなので、「攻略チャート」と名付けています。


ゲームを作り始めた時にぶつかる壁である「何をしたら良いのか分からない」という悩みを吹き飛ばしましょう!