【Unity】RPGを作るチュートリアルその107 エンディングのイベントを実装

【Unity】RPGを作るチュートリアルその107 エンディングのイベントを実装

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

第106回では戦闘関連で気になった部分として、ボス戦で逃走できないようにする機能の実装、全回復時の撃破フラグの扱いの修正を行いました。

今回はエンディングのイベントを実装していきましょう。

 

 

制作環境

MacBook Pro 2023 Apple M2 Max

Unity6 (6000.0.30f1) Silicon

 

作業内容と順序

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

 

チュートリアルの一覧

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

 

前回の内容

前回は戦闘関連で気になった部分として、ボス戦で逃走できないようにする機能の実装、全回復時の撃破フラグの扱いの修正を行いました。

 

各マップのイベントを実装

イベント機能について、コードの部分はある程度作成できたので、各マップで実際にイベントを組んでいきましょう。といっても村のイベントについてはイベントプロセスを実装する際にある程度作ってあるので、

  • 各マップをつなぐマップ移動のイベント
  • ボスゴブリンの会話と戦闘のイベント
  • エンディングのイベント

を実装すれば、当初想定していたイベントとしては実装が完了します。これまでのチュートリアルで上2つを実装できたので、イベント関連で(おそらく)最後のエンディングのイベントを実装していきます。

エンディングは、ボスゴブリンを倒して村に戻ってきた時に自動的に開始します。ボスゴブリンが魔王に関して匂わせをしている件を王都まで伝えにいく目的で旅立ちを始めます。この時、村長の家で母親やおっちゃんが見送ってくれるようにしたいと思います。キー入力なしでキャラクターが移動する処理も作りたいので、1つイベントプロセスを追加してからエンディングのイベントを組んでいきます。

 

キャラクターを移動させるイベントプロセスの作成

イベント中にキャラクターを任意の向きに移動させる機能を作りたいと思います。歩数もイベントのInspectorウィンドウから設定できるようにします。

キー入力とは別に移動させる機能については、「CharacterMover」に実装していきます。移動が完了したことをイベントプロセス側に通知するため、インタフェースを作っておきます。作業の順番としては、

  • 移動完了を通知するインタフェースの作成
  • 「CharacterMover」で外部から移動させる機能の追加
  • キャラクターを移動させるイベントプロセスの作成

で進めていきたいと思います。

 

移動完了を通知するインタフェースの作成

イベントプロセスから呼び出した移動が完了したタイミングで再びイベントプロセス側に通知することで、後続の処理を行うことができます。そのため、まずはインタフェースから作成していきましょう。

Projectウィンドウから「Assets/Scripts」のフォルダを開き、空のスクリプトファイルを作成します。名前は [ICharacterMoveCallback] にしました。

インタフェースの作成
インタフェースの作成

 

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

移動が完了した時にはOnFinishedMove()を呼び出して通知を行います。

 

「CharacterMover」で外部から移動させる機能の追加

「CharacterMover」ではキャラクターを外部から移動させる機能を追加します。主人公であればキー入力によって移動したり、NPCであれば移動の頻度に応じて次に移動する方向を決定していますが、これに加えて外部から移動させるメソッドを追加します。

フィールドの宣言部では既存の「_isCheckPostMove」の下に「_moveCallback」のフィールドを追加します。このフィールドでコールバック先をキャッシュします。

 

既存のGetMoveDirection()のメソッドの下に、外部からキャラクターを移動させるForceMoveCharacter()のメソッドを追加します。移動処理の待ち合わせを行いたいので、ForceMoveCharacterProcess()のコルーチンも実装しました。

引数の「direction」で移動する方向を、「steps」で歩数を決めます。「checkPostMove」の引数は、移動後にPostMove()の処理を行うかどうかのフラグです。例えば主人公を動かす場合、PostMove()では移動先のイベントを確認したりエンカウントしたりする処理を行うため、必要がなければfalseを渡します(今回はtrueで進めます)。

コルーチンの中では、for文を使って歩数の分だけ移動処理を行います。既存のMoveCharacter()の処理を呼ぶことで、移動中フラグの「_isMoving」がtrueになるため、移動完了までwhileで待つようにします。

指定した歩数分移動したら、コールバック用のメソッドを呼び出します。

 

キャラクターを移動させるイベントプロセスの作成

続いてイベントプロセスを作成していきます。このイベントプロセスからは、先ほど「CharacterMover」で実装したメソッドを呼び出すようにします。今回エンディングを作る際に動かしたいのは主人公なので、イベントプロセス内で「PlayerMover」への参照を取得して動かすようにします。

主人公のゲームオブジェクトはイベントが所属するマップのPrefab外にあるので、動的に取得するようにしています。同じマップのNPCを動かす場合は、Inspectorウィンドウから対象のゲームオブジェクトをアサインできる形でイベントプロセスを追加すると良いかと思います。

Projectウィンドウから「Assets/Scripts/Event/Process」のフォルダを開き、MonoBehaviourのスクリプトファイルを作成します。名前は [EventProcessMovePlayer] にしました。

主人公を移動させるイベントプロセス
主人公を移動させるイベントプロセス

 

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

移動の完了通知を受け取るため、「ICharacterMoveCallback」のインタフェースを実装しています。

フィールドとして、向き、歩数を設定できるようにします。また、「_isWaitMove」のフラグでは移動の完了を待つかどうかを設定できるようにします。完了を待つ場合はOnFinishedMove()のコールバックが呼ばれた時に次のイベントプロセスに進むようにします。

Execute()では「PlayerMover5」への参照を取得して、先ほど作成したForceMoveCharacter()のメソッドを呼びます。上で触れましたが、「_isWaitMove」のフラグがfalseなら完了を待たないで次のイベントプロセスを呼び、trueならコールバックを受け取って次のイベントプロセスを呼びます。

 

エンディングイベントの実装

さて、一仕事終えた感じがありますが、今回の主題はエンディングイベントの作成です。シーン内の「Map_0001_Village」を表示状態にして、イベントを作り込んでいきましょう。

「NPC_Chourou」の下にある「EventPages」にて、イベントページを追加します。既存の「EventPage3」を複製して名前を [EventPage4] にリネームしましょう。

イベントページの追加
イベントページの追加

 

イベントプロセスのゲームオブジェクトを以下のように作成します。

ゲームオブジェクト名 アタッチするスクリプト
ChangeDirection EventProcessChangePlayerDirection
ShowMessage EventProcessMessage
MoveCharacter EventProcessMovePlayer
Wait EventProcessWait
ShowMessageNarration EventProcessMessage
Wait2 EventProcessWait
ShowMessageEnd EventProcessMessage

 

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

 

イベントプロセスのつながりは以下のように設定します。

ゲームオブジェクト名 フィールド名 アサインするプロセス
EventPage4 Start Process ChangeDirection
ChangeDirection Next Process ShowMessage
ShowMessage Next Process MoveCharacter
MoveCharacter Next Process Wait
Wait Next Process ShowMessageNarration
ShowMessageNarration Next Process Wait2
Wait2 Next Process ShowMessageEnd
ShowMessageEnd Next Process なし

 

また、設定変更が必要なイベントプロセスでは以下のように設定しました。デフォルト値を使う場合は表から省略しています。

ゲームオブジェクト名 フィールド名 設定値
ChangeDirection Target Direction Back
ShowMessage Messages/要素0 <長老>
アレンよ、よくやった!
ShowMessage Messages/要素1 <母親>
よく頑張ったわね、アレン。
ShowMessage Messages/要素2 <おっちゃん>
これでお前も旅に出られるな!
ShowMessage Messages/要素3 <長老>
ゴブリン族は魔王のために動いていたようじゃな。
これは王都に伝えておかねばならん。
ShowMessage Messages/要素4 <長老>
アレンも力を示してくれたことじゃし、
王都までこのことを伝えに行っておくれ。
ShowMessage Messages/要素5 <アレン>
はい、行ってきます!
MoveCharacter Move Steps 3
ShowMessageNarration Messages/要素0 ゴブリン族の長を倒して旅立つアレン。
これが世界を股にかけた冒険の始まりだったとは
まだ誰も知らなかったのです。
ShowMessageNarration Messages/要素1 シンプルRPG、おしまいっ!
Wait2 Wait Time 3
ShowMessageEnd Messages/要素0 このチュートリアルを元に、自分の思い描いた世界を作ってね!

 

条件の設定

ボスゴブリンを倒した後に「EventPage4」を実行したいので、「Conditions」の下にある「EventPageConditionFlag」にて、「FlagName」を [DungeonBossWin] に、「State」を [true] にします。

条件の設定
条件の設定

 

「EventPage4」では、条件として先ほど設定した「EventPageConditionFlag」をアサインし、「Event Trigger」では [Auto] を選択します。

条件と起動方法の設定
条件と起動方法の設定

 

グラフィックの設定

続いてグラフィックの設定を行います。といっても村長はその場から動かないので、左の家にいる母親と、右のお店にいるおっちゃんに関して、ボスゴブリンを倒した後は表示されないようにします。それに加えて、エンディングイベント中は村長の家にいるようにしたいので、画像のみ表示するイベントを村長の家に配置したいと思います。

まずは作成済みの「NPC_Mother」、「NPC_Man」のNPCのゲームオブジェクトにて、以下の作業を行います。

No. 作業内容 画像
1 既存の「EventPage」の複製後、「EventPage1」「EventPage2」にリネームし、「EventPage2」のイベントプロセスを削除

イベントページの複製
イベントページの複製
2 「EventPage2」の「EventPageConditionFlag」にて「FlagName」を [DungeonBossWin] に、「State」を [true] に設定

条件の設定
条件の設定
3 「EventPage2」では、条件として先ほど設定した「EventPageConditionFlag」をアサインし、「Event Trigger」では [None] を選択、「Start Process」はnullにする

条件と起動方法の設定
条件と起動方法の設定
4 既存の「EventGraphicRecord」を複製して合計2つにした後、それぞれ名前を [EventGraphicRecordVisible][EventGraphicRecordInvisible] にリネーム

グラフィックレコードの複製
グラフィックレコードの複製
5 「EventGraphicRecordVisible」で対応するイベントページとして「EventPage1」をアサインし、「Sprite」にそのキャラクターの正面の画像、「Animator Controller」にそのキャラクターのアニメーターコントローラをアサイン

グラフィックの設定
グラフィックの設定
6 「EventGraphicRecordInvisible」で対応するイベントページとして「EventPage2」をアサインし、「Sprite」に透明な画像の [event_indicator_transparent]、「Is Stop Animator」にチェックを入れる

透明なグラフィックの設定
透明なグラフィックの設定
7 「EventGraphicController」で「Event Graphic Records」、「Sprite Renderer」、「Animator」をそれぞれアサイン

グラフィックコントローラの設定
グラフィックコントローラの設定

それぞれのゲームオブジェクトについて設定が終わったら、次はエンディングで村長の家にグラフィックを表示するためのイベントを作成します。といっても新規で作るのではなく、「NPC_Mother」、「NPC_Man」を複製し、表示条件を入れ替えることで実現できます。

こちらは以下の手順で作業を進めていきます。

No. 作業内容 画像
1 「NPC_Mother」を複製し、名前を [NPC_Mother_Ending] に変更

「NPC_Man」の場合は名前を [NPC_Man_Ending] に変更

ゲームオブジェクトの複製
ゲームオブジェクトの複製
2 Inspectorウィンドウからタグを [Untagged] に変更し、「Box Collider 2D」のコンポーネントを外す

「NpcMover」では「Move Frequency」を [Never] に変更

「Transform」にて以下の設定を行う

NPC_Mother_Ending – X:6.5, Y: 12.5

NPC_Man_Ending – X:8.5, Y: 12.5

NPC_Mother_EndingのTransform
NPC_Mother_EndingのTransform

 

NPC_Man_EndingのTransform
NPC_Man_EndingのTransform
3 「EventGraphicRecordVisible」の「EventPages」を「EventPage2」に変更

フラグがtrueで見えるように
フラグがtrueで見えるように
4 「EventGraphicRecordInvisible」の「EventPages」を「EventPage1」に変更

通常時は見えないように
通常時は見えないように
5 「EventPage1」の「Event Trigger」で [None] を選択、「Start Process」はnullにする

起動方法の設定
起動方法の設定

 

ここまでの設定が終わったら、「Map_0001_Village」の「Overrides」のプルダウンから [Apply All] をクリックしてPrefabに変更を適用します。

 

動作確認

エンディングのイベントの動作を確認してみましょう。確認前に、「Map_0001_Village」、「Map_0002_Field」、「Map_0003_Dungeon」を非表示にしておきます。

ゲームを開始したタイミングでは、村長の家の「NPC_Mother_Ending」と「NPC_Man_Ending」が表示されていないことを確認します。実は一瞬だけ表示されますが、タイトル画面を実装した際にはゲーム開始時にフェードインしてくる想定なので、その時には見えないようになります。

ボスゴブリンを倒して村に戻ってきた際に、エンディングのイベントが始まり、メッセージが表示されること、主人公が3歩下に移動することを確認します。確認中は定義データのボスゴブリンのHPを減らしておくとすぐに確認できます。

エンディングを実装できると感慨深いですね
エンディングを実装できると感慨深いですね

 

今回のブランチ

 

まとめ

今回はエンディングのイベントを実装しました。フラグに応じてキャラクターの表示や非表示の状態を切り替えることで、イベントシーンに対応した形で配置することができます。

次回はタイトル画面のUIを実装していきます。

     

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

CTA-IMAGE

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


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


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