今日は夢天狗さん(@yumetengu26)からのリクエストを受けて、Camera で Actor の特定の部位を追尾する機能について紹介します
Camera による Actor の Tracking の方法について #
考えられる方法は 2 種類あります
- CineCameraActor の
LookAt Tracking
機能を使う FindLookAtRotation
ノードで Camera からみた Actor の方向を計算する
CineCameraActor の機能を使った方法 #
CineCameraActor にはデフォルトで LookAt Tracking
という機能が備わっています
これは、設定した Actor を自動的に追いかけてくれる機能です
ただしこの機能で指定できるのは Actor の単位のみで、モーショントラッキングのときのような、Actor をその場に置いたまま SkeletalMeshComponent が自由に動く場合にはうまくいきません
別途 Tracking 用の Actor を用いる必要があります
Tracking 用の Actor を作ってみる #
Actor を継承し、Tracking 用の Actor を作成します
Tracking に使うだけなら Actor であれば何でも良いのですが、便利に使えるように設定をしてみましょう
Box は Actor の位置をわかりやすくするためのものです
Collision は NoCollision に設定しておきましょう
TextRender や Billboard もおすすめです
変数設定 #
下記の変数を作り、Level 上で設定できるようインスタンス編集可能にしておきましょう
変数名 | 型 | 備考 |
---|---|---|
AttachTargetActor | Actor | Tracking を行う対象の Actor 参照 |
AttachedSocket | Name | Tracking したい部分(Bone/Socket)の名前 |
ノードの実装 #
Attach 関連のノードを実装します
基本的に BeginPlay で Attach すればよいですが、実行前にも Attach して動作確認できるよう、CallInEditor を ON にしたイベントにしておきます
(Event 名が日本語なのは、この名前で Level の詳細パネルに出るためです)
GetComponentByClass
を使い、Tracking を行う Actor の SkeletalMeshComponent の参照を取得します
その SkeletalMeshComponent に、Tracking 用の Actor を AttachActorToComponent
ノードを使って Attach します
Tracking したい Bone の位置にピッタリ合わせるために、LocationRule は SnapToTarget にしておきます
使い方 #
- Tracking 用の Actor を Level 上に配置
- Tracking 用の Actor を選択し、
AttachTargetActor
に Tracking したい Actor を設定 - Tracking したい位置の Bone 名を
AttachedSocket
に設定 アタッチ
ボタンをクリックすれば、Actor が Tracking したい位置にくっつく- CineCameraActor の
Actor to Track
にこの Actor を指定する
うまくくっつかない場合は、Bone 名が合っているか確認してみましょう
FindLookAtRotation を使った実装 #
CineCameraActor ではないゲーム用の Camera の場合や、LookatTracking を使わない場合は、 FindLookAtRotation
ノードを使った方法を試してみましょう
FindLookAtRotation に使用する Location を取得する方法は、何らかの SceneComponent を SkeletalMesh に Attach して、そこから取得する方法と、SkeletalMesh の Bone から直接取得する方法の 2 通りがあります
お好みで選択してください
制御用クラスの実装 #
Camera の向きを制御する用の Actor を作成します
変数設定 #
下記の変数を作り、Level 上で設定できるようにインスタンス編集可能にしておきます
変数名 | 型 | 備考 |
---|---|---|
CameraActor | CameraActor | 制御する CameraActor |
TargetActor | Actor | Tracking する対象の Actor 参照 |
RefCamTrackPoint | SceneComponent(Tracking 用の Component) | Tracking に使う Component (Component から Location を取る場合のみ) |
TargetSocketName | Name | Tracking する Bone/Socket 名 (Bone から Location を取る場合のみ) |
RefSkeletalMesh | SkeletalMeshComponent | Tracking する SkeletalMeshComp (Bone から Location を取る場合のみ) |
Tracking 用の SceneComponent を作成する #
SceneComponent を継承し、Tracking 用の Component を作成します
ロジックの実装は不要です
Bone から直接取得する場合には、作成する必要はありません
Tracking 用の SceneCompnent を設定する #
Tracking したい場所に、作成した SceneComponent を Attach しておきます 画像は head に Attach した例です
Bone から直接取得する場合は、この操作も必要ありません
Tracking 用のロジック実装 #
SceneComponent を用いる場合は下記の画像のように実装します BeginPlay では GetComponentByClass で Tracking 用のマーカーを指定し、Tick でその WorldLocation を取得して、FindLookAtRotation を使用して向きを計算します
Bone から直接取得する場合は、BeginPlay で取得する参照が、SkeletalMeshComponent に変わります
こちらは Tick で GetSocketLocation
を使って WorldLocation を取得し、FindLookAtRotation に使います
補完(ブレ補正)について #
モーショントラッキングのような微妙なブレがある場合に、FindLookAtRotation
の結果をそのまま使うと、Camera の方もブレがでて良くない状態になる場合があります
その場合は、Rotator の変数を一つ追加し、 RInterpTo
ノードを使って補完することで、細かいブレを抑制する事ができます
InterpSpeed を低くするとより抑制が効きますが、その分 Camera の動きも遅れるので、良い感じのところを探って調整してください
CineCameraActor を使用している場合は、 LookAt Tracking Settings
に Look at Tracking Interp Speed
という項目があるので、これを使用してください
サンプルプロジェクト #
サンプルプロジェクトを公開しておきます
https://drive.google.com/drive/u/1/folders/1vzEub48i0HvWZQPrbYg2ZIyiAWgk3FwJ
参考文献 #
Cine Camera Actor (公式ドキュメント)
https://docs.unrealengine.com/4.27/ja/AnimatingObjects/Sequencer/Cameras/CineCameraActors/
Find Look at Rotation (公式リファレンス)
https://docs.unrealengine.com/4.27/en-US/BlueprintAPI/Math/Rotator/FindLookatRotation/