UE4でキャラクターをタッチした場所に移動させる

キャラクターの移動制御で、タッチ、又はマウスクリックした箇所にキャラクターを移動させてみたいと思います。
※画像はクリックで拡大できます
キャラクターの準備
今回移動させるキャラクターの準備をしました。キャラモデル自体はアセットを適当に使っていきます。
作成したブループリントクラスのGameModeBaseクラスに、これまた作成したPlayerControllerクラスと、「DefaultPawn」として作成したCharacterクラスをセットした状態に持って行ってあります。
MeshコンポーネントのSkeletal Meshにお好みのキャラクターモデルをセットし、ArrowComponentの矢印に向きを合わせておきます。
Characterクラスのコンポーネントは下記の画像のような状態です。
SpringArmにCameraを付けて、トップビューの視点にしてます。この時、SpringArmのトランスフォーム、回転を「相対」→「ワールド」に変更してキャラクターの回転でカメラも一緒に回転しないようにしています。
CharacterMovementコンポーネントのCharacter Movement(Rotation Settings)にある「Orient Rotation to Movement」のチェックボックスをONにして、キャラクターが移動方向を向くようにします。
TouchPointToWorldは、クリックした箇所が分かりやすくなるように表示するDecalです。後ほどCharacterコンポーネントのブループリント、イベントグラフで制御します。
タッチした箇所に移動するブループリント
PlayerControllerクラスのブループリントを開き、イベントグラフで下記画像のように組みます。
ここでやってる事は、主に入力制御の取得でありタッチ、またはマウスクリック時に「GetHitResultUnderCursorbyChannel」か「GetHitResultUnderFingerbyChannel」でタッチ指orクリック時マウスカーソルの下にあるオブジェクトを取得し、「MoveToTouchLocation」関数内で取得したオブジェクトのタッチorクリック箇所座標へ移動する処理を行っています。
「インプットアクション SetDestination」はプロジェクト設定のエンジン – インプットに定義したマウスクリック等のイベントです。
次に実際にキャラクターを座標移動させている関数、MoveToTouchLocationが下記になります。
やってる事は(キャラクターの位置ベクトル)ー(タッチした物体の目標座標ベクトル)でキャラクターが移動する方向のベクトルを算出し、そのベクトルの大きさ(移動距離)が「MinTouchDistance(自分で容易した定数)」を上回る場合、BreakHitResultによる目標座標へ「SimpleMoveToLocation」で移動させる処理です。
タッチポイントデカールのブループリント
タッチorクリックした際の場所をわかり安くするための、デカール表示制御のブループリントが下の画像です。
デカールのブループリント制御はCharacterクラスのブループリント、イベントグラフに記述しています。
こちらもやってる事はキャラクターの移動と途中まで一緒で、GetHitResultUnderCursorbyChannelによってカーソルorタッチ下のオブジェクト取得、BreakHitResultで座標を取得し「SetWorldLocationAndRotation」でデカール表示座標をセットしています。
BreakHitResultで法線ベクトル、MakeRotationfromAxesでRotatorを得てデカールがカメラの方に常に向くようにもなっています。
キャラクターカメラの有効化
CharacterクラスでSpringArmで付けたカメラをゲーム開始時に有効化するために、Characterクラスのイベントグラフにブループリントを記述します。
イベント BeginPlayでゲーム開始直後にSpringArmに付けたCameraを「Activate」で有効化しています。
NavMeshBoundsVolumeの設置
今までの設定で、キャラクターとタッチ位置デカールは正常に動作するように思いましたが、キャラクターが動きませんでした(汗
デカールは正しくマウスカーソル、タッチ位置に表示されるようにはなっていますが、キャラクターはピクリとも反応しません。
で、Characterクラスの「Pawn – AI Controller Class」に「AIController」が設定されているからか、はたまたキャラクターの移動がSimpleMoveToLocationによって行われているせいか、恐らく後者だと思いますがNavMeshBoundsVolumeコンポーネントの範囲内で無ければ動きませんでした。
さっそくNavMeshBoundsVolumeを設置してキャラクターの移動範囲を決定します。
キャラクターが移動するマップ全体を覆うようにNavMeshBoundsVolumeを設置してみました。NavMeshBoundsVolumeの大きさや形状は詳細で設定できます。
キャラクターをタッチorクリックで動かしてみる
これまでの設定でキャラクターが動くはずなので、早速動かしてみます。
無事キャラクターをタッチorクリックした箇所に動かす事ができました!
ディスカッション