📄

【UE5】コントロールリグでLookAtを作る

に公開

はじめに

プレイヤーの方を見るNPCという設定でコントロールリグによるLookAt機能を作ってみました。
https://youtu.be/plidIYHMZaE

プレイヤーの位置情報をコントロールリグに送って操作する方法はヒストリアさんの記事を参考にさせていただきました。
https://historia.co.jp/archives/46931/

なるべくリアルな挙動を目指してコントロールリグで色々と設定を行っていますので、
この記事ではそれを中心に紹介します。

1.頭の向きを制御する仕組みの作成

aim用のコントローラーを作成し、AimConstraintを使って頭がコントローラーの方向を見るようにしています。今回はアップベクトル用のコントローラーを作りませんでしたが、作った方がより挙動の精度が高くなると思います。最終的にこのコントローラーはプレイヤーの位置に合わせます。

2.頭の可動範囲を設定

このままだと頭がねじれるぐらい回転してしまうので、回りすぎないように回転値に制限をかけます。
こちらも最初に紹介したヒストリアさんの仕組みを参考にさせていただきました。
やっていることは以下になります。

  • AimConstraintで動かした頭のボーン回転値を取得(クォータニオン)
  • ToEulerでクォータニオンをオイラーに変換
  • clampでX回転を-40~40の範囲に制限
  • 頭のボーン回転値に設定

3.体の向きが首と連動して動くように設定

頭だけでは不自然なので身体も回転するようにしました。
基本的には頭と同じでボーン毎に専用のAimコントローラーを作成し、AimConstraintでコントローラーの方向を見るようにしています。Headのコントローラーを流用したかったのですが上手くオフセットをかけることができなかったため、少し雑ですがコントローラーを用意する方法で作成しました。
腰に近づくほど回転値を抑えたかったのでノードの一番下のWeightで調整しています。

最終的にHeadのAimコントローラーをプレイヤーの位置に合わせるので、連動して動くようHeadのAimコントローラーの子にしています。

4.部位ごとにコントローラーを向くタイミングを遅らせる

動き始める順番を頭→上半身→腰という順番にしたいのでAccumulateLerpノードを使いました。
IntegrateDeltaTimeにチェックを入れてBlendの値を調整しています。

以下のようにAimで動いた回転値をGetで取得し、AccumulateLerpでタイミングをずらしています。

5.Aimの動きに合わせて腰の移動を設定

より自然な動きにするため腰の移動も入れてみました。
上を向いたときは腰を前に、下を向いたときは腰を後ろに、左右も同じような感じに若干動かしています。動きは再生されている待機モーションに加算させたいので動く分の値を計算して足しています。

  • headのaimコントローラーをコピーしてデフォルト位置を保持するコントローラーを作成
  • 2つのコントローラーのTranslationの差をSubtractノードで計算
  • Multiplyノードで小さい値を掛けて、腰に渡す移動値を調整
  • 腰のボーンのトランスフォームを取得、その値と計算した値をAddノードで加算
  • 加算した値を腰のボーンに設定

    ※画像では見やすくするためTranslationYの計算を省いています。

6.足にIKを設定

腰を動かすと足が動いてしまうのでIKを設定して固定しています。

7.腕の動きを補正

上下を見たときの身体の動きに腕が追従して目立っていたので回転しないようにしました。

  • 右腕と左腕のボーンのTransformを記録しておくための変数を作成
  • 処理の最初の方でTransformを記録
  • 処理の最後の方で記録したTransformを使ってRotateを設定

まとめ

動きとしてはそれなりに自然なものが作れたと思いますが、プレイヤーを見ている感じが少し薄いと感じたので、実際はゲームに合わせてもっと作りこんでいく必要がありそうです。また今回紹介した実装方法以外に様々な作り方があるかと思いますので、参考としていただけたら幸いです。

Discussion