UE4ゲーム制作入門六日目
一人UE4ゲーム制作入門アドベントカレンダー六日目です。
今日は昨日放り投げた、攻撃の続きを実装していきます。
そして、一番最初に言ってしまうと、前回のプレイヤーのアニメーションほぼ全とっかえになります。
本来はBlendさせて上半身だけ銃構えるのにして、楽をしようと思っていたのですが、逆にめんどくさいことになったので、もともとあるやつをまたパクります。
アニメーションとかモデルのアセットの準備
言い訳も終わったところで始めていきましょう。まずは、攻撃アニメーションを持ってきます。マーケットプレイスからAnimationStarterPackを持ってきます。サムネイルがグレーマンがピストル構えてるやつになります。
次にライフルのモデルを持ってきます。ShooterGameというラーニングにあるサンプルプロジェクトから、Rifleというスケルタルメッシュを持ってきます。
アニメーションのリターゲット
今回の準備は整いました。まずは、AnimationStarterPackからRifleと名前のついたアニメーションを僕らが使っている方のグレーマンに適用します。AnimationStarterPackに入っている、グレーマンにすり替えてもいいのですが、アニメーションリターゲットの説明に使えるのでやります。
まずはコンテンツブラウザの検索からRifleのアニメーションを探します。検索結果がこんな感じになったら全部を選択して、右クリックしてアニメーションリターゲットします。
右下でリターゲットした後のアニメーションをエクスポートする先を選びます。
①と書かれたところのチェックを外さないとリ・ターゲットするスケルトンを互換性がないスケルトンを表示させて適用させることができません。
チェックを外した後②の部分にUE4とうつといま使ってるグレーマンのスケルトンが選べます。
他にもBS_JogとかAim_Space_Hipとかもリターゲットしておきます。
ABP_Playerの編集
終わったらアニメーションブループリントを編集していきます。いじくりすぎて記憶があやふやになってしまっているのですが、Idle/RunからIdleにステートの名前を変えて、アニメーションをIdle_Rifle_Hipに変えて、新しくRunステートを作って、BS_Jogをアニメーションにします。見てもらったらわかると思いますが、BS_Jogはブレンドスペースです。
speedとDirectionのfloat変数をなければ、作ってつなげます。速さと向きを制御します。
待機と移動アニメーションを分離させたことによって遷移部分を多少変えなければなりません。
まず、IdleとRunの間に遷移条件をつけます。
Idle > Run : speed > 10
Run < Idle : speed <= 10
IdleとJump関連
Idle > JumpStart : isInAir?がtrue
Idle < JumpEnd : GetRelevantAnimTimeRemaining() < 0.2 且つ speed <= 10
RunとJump関連
Idle > JumpStart : isInAir?がtrue
Idle < JumpEnd : GetRelevantAnimTimeRemaining() < 0.2 且つ speed > 10
です。ライフルを抱えたジャンプモーションもありますが、今のやつでなかなかおもしろいのでそのままにしておきます。
次にAimOffsetを作ります。しかし細かい説明はすべてすっ飛ばします。公式のを参考にしてください。
私が行った簡単な流れだけは説明しておくと、
・PlayerのAnimationフォルダにAimOffsetフォルダを作成
・Aim_Space_Hipのアニメーションをリターゲットし、AimOffsetフォルダへ
・Aim_Space_Hipアニメーションから各9方向への向きのポーズを作成
・PlayerAimOffsetという名前のAimOffsetを作成
・先ほど作ったAimOffsetのパラメータを調整し、先程作ったポーズを適用
こんな流れです。細かいパラメータの値や方法は先程の公式に書いてあります。バージョンが古いですが、特に操作は変わってないので問題ありません。
AimOffsetが完成したら、ABP_Playerで実際に動かせるようにしましょう。
大体公式の説明と同じですが、微妙に変えた部分があるのでその辺だけ説明しておきます。
公式ではしゃがみとか線形補間で滑らかにしていますが、こっちではその辺簡略化してます。
GetAimOffsetという新しく作った関数の戻り値の回転のYawとPitchを新しく作った2つのfloat変数にセットしています。この2つで、AimOffsetの向きを制御します。
GetAimOffsetはこんな感じです。コントローラとアクタの回転の差分を取ってます。多分すごい無駄です。この辺から僕の頭の悪さがにじみ出始めます。
ライフルをもたせる
次にライフルをもたせましょう。グレーマンのスケルタルメッシュにアタッチする先のソケットを設定します。
ソケット名から位置とか回転とか取れて、アタッチしたアクターがアニメーションに追随してくれるようになるのでとても便利です。公式をみて覚えましょう。
ちなみに僕は全然わからないです。
次に、ライフル自体を作りましょう。Playerフォルダの中にWeaponフォルダを作り、その中にActorクラスを親としたBP_Rifleブループリントクラスを作ります。
ウィンドウを開いて、コンポーネントルートにSceneコンポーネントを配置し、スケルタルメッシュとArrowコンポーネントをその下に追加します。スケルタルメッシュにはSooterGameから持ってきたRifleを設定し、-90度回転させます。
コンポーネントの設定が完了したら、GetShotPos関数を作ります。中身はこんな感じです。
昨日作った弾は前方向に延々と飛んで行くので、自分の見ている方向へ向かせてやらねばなりません。なおかつ、銃口から出ていないとおかしいので先程作ったArrowコンポーネントの位置から生成する位置を設定しています。
戻って、BP_PlayerのBeginPlayにこれを作ります。ライフルを、プレイヤーが生成された瞬間に生成してから、先程作ったソケットにアタッチしています。あと、RifleのGetShotPosを呼び出しやすいように、生成したアクターを変数に格納しています。
AttachWeaponの中身はこんな感じです。単純にしてます。
弾を撃てるようにする
ついに、弾を発射できるようにします。
まずは入力でShotを作ります。プロジェクト設定のインプットのActionにShotという新規アクションを追加します。対応する入力キーはなんでもいいですが、僕は左コントロールにしています。とてもやりにくいので、おとなしく左クリックにしておくとよいでしょう。
設定が終わったら、BP_Playerに移動します。新しくShot関数を作りましょう。中身はこんな感じで、ライフルのGetShotPosをBP_Playerに同じ名前で作ってそれを使って呼び出し、BP_ShotをSpawnActorFromClassから生成しています。その後の2つの変数は今はなんの役にも立ってないので放置です。あとで色々変更するときに使います。
最後にBP_PlayerControllerで、インプットアクションのShotイベントを設定します。設定したボタンが押されたとき、BP_PlayerからShot関数を呼び出します。先ほどと同じですが、離したときのイベントに設定している変数は無視してください。
これで、全部終了です。コンパイルを通してエラーが無ければプレイしてみましょう。上下に銃口がカメラに合わせて動くようになっていて、向いている方向へと弾が飛ぶようになっているはずです。
おまけ
ちなみに、単純に銃口の位置だけを取って弾を発射するとこうなります。
さすがに草しかはえない pic.twitter.com/rajyqICnsS
— 故・白鳥隆士@一人UE4アドカレ (@shiratori1221) 2016年12月4日
とても雑でわかりにくいですが、これにて今日はおしまいです。アニメーション全然使ってなかったのでとても、手間取りました・・・。