それでは、格闘ゲームが作れるプログラムのレベルブループリントとウィジェットプループリントの導入部分までを解説していきます。
ですが、その前に自分のこれまでの経緯を少しお話しておきます。
自分はゲーム業界で働いていたわけでもないし、プログラムを専門に仕事をしていたわけでもありません。
そんな中で、UnrealEngineの存在を知り、最初はちょっと触ってみる程度で始めてから、1年半ほどずっと触っていた結果、このプロジェクトを完成させることができました。
プログラムと聞くと大変難しいイメージがありますが、Blueprintがその理解を非常に助けてくれています。
これから学び始める人は、私が苦労した時間よりも短い時間で、このプロジェクトの内容を理解できると思いますので、是非参考にしていただければと思います。では解説していきましょう。
まずは、今回の説明で使用する3つのファイルを紹介します。
1つ目は、StagesフォルダのStart_hereレベルファイルを開き、 エディタ上部のブループリントメニューから開けるレベルブループリントです。
2つ目は、メニュー画面等でUIを制御するWidgetブループリントです。
3つ目は、プレイヤーの入力を受け取り、ゲーム全体を制御しているPlayerControllerブループリントです。
それでは、レベルブループリントから解説を始めます。
BeginPlayのノードから処理が開始され、最初のブランチではインデックスが1のPlayerControllerが有効であれば、そのまま処理を継続、無効であれば、CreatePlayerを実行し、Player02用の PlayerController を生成します。
(インデックスが0のPlayer01用のPlayerControllerはゲームを実行した時点で自動生成されます。)
CreatePlayerのController_Idが-1になっているのは、空いている番号から順番に付与するという意味です。初回のBeginPlayイベントの実行時は、最初のブランチでFalseとなり、CreatePlayerを実行しますが、その後ゲームプレイ中にタイトル画面へ戻る処理を実行すると、再度BeginPlayノードから処理されることになり、その場合はインデックスが1のPlayerControllerは、有効となっているため、CreatePlayerは実行されずに次の処理へ進みます。
次にWidgetBlueprintを作成して、Add to Viewportで画面へ出力します。
Zorderの番号は大きいほど手前に表示されますが、このプロジェクトでは1つのWidgetしか使用していないので、どの値でも機能します。
その後、このゲームではマウスの操作は不要ですので、クリックとマウスカーソル表示の機能をOFFにします。
ここから先は、Widget_Blueprintで処理を継続しますので、WidgetフォルダにあるWidget_Fightingを開きます。
Widget_Blueprintでは、イベントConstructとTickの処理を開始しますが、まずは、イベントConstructから説明します。
Player01と02が生成したPlayerContollerには入力モードを設定する必要があり、上の図ではUIとゲーム中の両方で入力できるようにする「Set Input Mode Game and UI」を使用しています。
次に、Widget_Fighting内で、このプロジェクトの PlayerContoller であるCommon_Controller型の変数「Controller_Ref」を定義しており、これに、Player01の PlayerContoller を代入しています。
(Player02の PlayerContoller に対しては「Controller_Ref02」へ代入しています。)
例えばキャラクターセレクト画面で、キャラクターをスポーンするのは、 PlayerContoller の機能になりますが、スポーンするタイミングはWidget_Fighting上で設定しており、「Controller_Ref」 を経由してキャラクターをスポーンするイベントを参照しています。
次にPlayer01のCommon_Controllerで、Widget_blueprintであるWidget_Fighting型の変数を定義しており、これにWidget_Fighting自身を代入しています。
これは、例えば、Widget_Fighting内で設定したサウンドボリュームをCommon_Controller内で、この変数を経由して値を 参照しています。
さらに、Common_Controller内で、整数型の「Controller_ID」に対し、「0」を代入しています。
このプロジェクトでは、1つのPlayerControllerで、2つのコントローラの入力を処理しており、この「Controller_ID」の値に応じて、どちらのコントローラの入力であるか判断しています。
(Player02のController_IDに対しては「1」を代入しています。)
最後に、お互いのPlayerControllerの値を参照できるように、Player01のCommon_Controllerで定義した、「P02_Contoller」へPlayer02の PlayerController を代入、Player02のCommon_Controllerで定義した「P01_Contoller」へPlayer01の PlayerController を代入しています。
これにより、相手の攻撃の種類が何であるかなどの値をこの変数を経由して参照できるようになります。
その後は、 イベントConstruct が処理を開始した後、0.5秒後に「Begin to Title」というイベントが実行された後、キャラクターセレクト画面で使用するレベルをタイトル画面の裏側でロードし、かつ可視化しています。
さらにその0.5秒後に論理型の変数「Begin_Title」にTrueをセットしていますが、これはTick側の処理で使用します。
それでは、「Begin to Title」というイベントの説明をします。
まず最初に「For_Title」というWidget_Animationを処理していますが、Widget_Animationは次のように設定しています。
➀アニメーションさせたいボタンや画像を選択
➁「+アニメーションボタン」をクリック
➂アニメーションの名称を設定。今回はFor_Title。
➃トラックボタンをクリックして、アニメーションの効果を選択。
今回は”Color and Opacity“、”is Enabled” と “Render Opacity”を選択
➄0.5秒後にColor and Opacityが0→1.0、is Enabled がFalse→True、Render Opacityが0→1.0になるように設定。
(Render Opacityでボタン自体の描画、Color and Opacityでボタンに設定している画像の透明度を変更しています。)
これでボタンが徐々に表示されるアニメーションが作成できます。
アニメーション再生後、論理型の変数「End_Game」にFalseをセットしていますが、これは1回ゲームをプレイし終えてタイトル画面へ戻ってきたとき用の処理で、ゲームを終了したフラグのリセットとなります。
次に「Prepare_Animation」というマクロを処理していますが、マクロはこの場所だけではなく、他の場所でも同じ処理をする場合に役立ちます。
「Prepare_Animation」では各種Widget_animationを0.01秒だけ再生させています。
これは各種アニメーションが透明度を指定しているAlphaを初期的に「0」にしており、0.01秒だけ再生することで、Alpha「0」を有効にし、現時点で表示する必要のないアニメーションの処理を行っています。
これをしないと、下の画像のように、必要のないUIが初期的に表示されてしまいます。
上記の様にならないためには、アニメーションの設定でAlphaを初期的に「0」にして、0.01秒だけ再生するか、下の画像のようにデザイナー画面で、Alphaを初期的に「0」にして登録する方法があります。
「For_Title」というWidget_Animation再生されると、Animation_finishedのイベントが処理され、Player01のコントローラ入力を許可するフラグをTrueに設定しています。
次回はタイトル画面表示したときのTickの処理について説明します。
コメントを残す