プレイヤーの方を向く砲塔を作ったら、一瞬で振り向いてしまった。もう少し重そうに、狙いを定めながら回ってほしい。そんなときに使うのが、向きを少しずつ近づける補間です。
大切なのは、「どこを向きたいか」と「今の向きからどう近づけるか」を分けることです。この記事では、まずプレイヤーをすぐ向く砲塔を作り、そこへ補間を加えて動きの違いを見比べます。

この記事でわかること
- Rotatorの3つの角度と、水平方向を表すYaw
- 350度から10度へ回すときに、遠回りが起きる理由
- RInterp ToとLerpが計算する値の違い
- 砲塔がプレイヤーを追う速さを調整する方法
Rotatorは、向きを3つの角度で表す
UEで向きを扱うときによく使うのが、Rotatorという型です。Roll・Pitch・Yawという3つの角度をまとめて持ち、単位は度です。
| 成分 | 回転する軸 | 動きのイメージ |
|---|---|---|
| Roll | X軸まわり | 飛行機が左右に傾く |
| Pitch | Y軸まわり | 機首が上や下を向く |
| Yaw | Z軸まわり | 水平に左右を向く |
ここでの「軸まわり」は、その軸を回転の芯にするという意味です。UEの基本の向きはXが前、Yが右、Zが上です。Zを芯にして回すYawなら、上を向いたり横に倒れたりせず、水平方向に向きを変えられます。

今回の砲塔は、このYawだけを使います。砲身の正面をX方向へ伸ばし、土台の上で左右に旋回させます。
350度と10度は、見た目では近い
角度で少しややこしいのは、360度回ると元の向きへ戻ることです。350度と10度は、数値だけなら340離れていますが、向きとしてはすぐ隣です。
- 350 → 360(0)→ 10と進む:20度の近道
- 350 → 180 → 10と減らしていく:340度の遠回り
たとえば350と10を普通の数値として半分ずつ混ぜると、結果は180です。近道の途中である0度にはなりません。「少しだけ向きを変えたいのに、大きく回った」という現象は、こうして起こります。

今回のようにYawだけを追わせるなら、回転用の RInterp To を使います。Lerp(Rotator) を使う場合は、Shortest Pathも確認してください。これは「短い回り方を選ぶ」設定です。回転用という名前だけで、どんな設定でも同じ回り方になるわけではありません。
なお、350度と-10度は同じ向きです。取得した角度が負の値で表示されても、それだけで回転が壊れているとは限りません。
目標の向きを作り、実際に反映する
砲塔がプレイヤーを向くには、まず「どの向きならプレイヤーを向けるか」を求めます。その計算をするのが Find Look at Rotation です。
| 入出力 | 今回渡すもの |
|---|---|
| Start | 砲塔の回転軸の位置 |
| Target | プレイヤーの位置 |
| Return Value | StartからTargetを見る向き |
StartとTargetは、角度ではなく位置を表すVectorです。2つの位置を渡すと、StartからTargetへ正面のX方向を向けるRotatorが返ります。
ただし、これだけでは砲塔は回りません。計算した向きを、回したい部品へ設定する処理が必要です。後の実践では Set World Rotation を使い、砲塔の頭に結果を反映します。
相手が上や下にいる場合、Find Look at Rotationの結果にはPitchも含まれます。水平だけを向かせるには、Break Rotator で3つの角度へ分け、Yawだけを Make Rotator へ渡します。Make側のRollとPitchを0にすれば、水平方向だけの目標になります。

Breakは値を取り出す、Makeは値をまとめる、という関係です。難しい角度計算を書かなくても、この組み合わせで使いたい成分を選べます。
RInterp Toで、現在の向きを少し近づける
目標の向きをそのままSetすると、その更新で目標へ切り替わります。そこへ RInterp To を挟むと、現在の向きから目 標へ少し近づいた向きを計算できます。
これを繰り返す入口には、Event Tick を使います。基本的にはゲームが1フレーム進むたびに呼ばれるイベントで、Delta Seconds から前の更新との時間差を受け取れます。
| ピン | 入れるもの | 意味 |
|---|---|---|
| Current | 今の向き | ここから近づける |
| Target | 目標の向き | こちらを向きたい |
| Delta Time | TickのDelta Seconds | 前の更新から何秒たったか |
| Interp Speed | 今回は2から試す | 目標へ近づく強さ |
| Return Value | 計算結果 | この更新で設定する向き |
Delta Timeは、1回の更新に対応する経過時間です。1秒に何回更新できるかは状況で変わるため、「1回だから同じだけ回す」ではなく、実際にたった時間を渡します。
Interp Speedは、毎秒何度でも、完了までの秒数でもありません。 正の値では大きいほど目標へ素早く近づきます。また、同じ条件なら、目標から遠いときは大きく、近づくと小さく向きを変えるので、終わり際がゆっくりになります。
ここで重要なのが、次の繰り返しです。
- 今の向きと、今のプレイヤーを向く目標を読み取る
- RInterp Toで、今回の向きを計算する
- Set World Rotationで、その向きを反映する
- 次のTickで、反映後の向きからまた計算する
RInterp To自身が時間を進めたり、Actorを動かし続けたりするわけではありません。 Currentを開始時の向きに固定せず、毎回「今の向き」を読み直すから、目標へ近づいていきます。

回転以外にも、同じ考え方のノードがあります。
| ノード | 計算する値 | 使う例 |
|---|---|---|
| RInterp To | Rotator | 砲塔が相手を追って向く |
| VInterp To | Vector | カメラの位置を目標へ近づける |
| FInterp To | Float | 表示中のHPの数値を実際のHPへ近づける |
今回は回転なので、RInterp Toを使います。ほかの2つも、返ってきた値を位置や表示へ反映する処理と組み合わせます。
Lerpは、始まりと終わりの間を選ぶ
もう1つよく使う Lerp は、AとBの間のどこを使うかを、Alpha で選ぶノードです。Alphaを0〜1で使うと、0ならA、0.5なら中間、1ならBになります。
たとえばLerp(Rotator)で、RollとPitchは0のまま、Yawの0度から90度までを考えてみます。
| A | B | Alpha | 選ばれるYaw |
|---|---|---|---|
| 0 | 90 | 0 | 0 |
| 0 | 90 | 0.5 | 45 |
| 0 | 90 | 1 | 90 |
AとBをこのまま固定し、Alphaも0.5のままなら、何回計算しても45です。滑らかな動きにしたいときは、Alphaを時間に合わせて変え、その結果を毎回Setします。

たとえばTimelineで2秒かけてAlphaを0から1へ動かせば、決めた始まりから終わりまで2秒で変える動きを作れます。Lerpへ2秒という指定をするのではなく、2秒を管理するのはTimeline、途中の値を求めるのはLerpです。
| 作りたい動き | 使いやすい組み合わせ |
|---|---|
| 目標が動くたびに、今の向きから追いかける | Tick + RInterp To + Set |
| 決めた始まりから終わりまで、2秒で動く | Timeline + Lerp + Set |
これは用途から選ぶ目安です。Lerpでも、Aに毎回現在値を入れれば、Alphaが0.5のままでも値は近づいていきます。ただし、そのまま「毎フレーム半分ずつ」とすると、更新回数で追従の速さが変わります。今回の砲塔では、経過時間を渡して使うRInterp Toで組みましょう。
実践:プレイヤーを追う砲塔を作る
Third PersonのBlueprintプロジェクトを使います。新規作成時に「Variant」がある版では None を選びます。Blueprintでコンポーネントと変数を作り、ピンをつなぐ操作を知っていれば進められます。
作るのは、土台を固定したまま、上の砲身だけがプレイヤーを向く砲塔です。弾は発射せず、旋回の違いに絞って試します。
1. 回転軸と砲身を分ける
Actorを親にしたBlueprint Class BP_Turret を作り、次のコンポーネントを加えます。
| 名前 | コンポーネントの種類 | 親 | 役割 |
|---|---|---|---|
| Base | Static Mesh | DefaultSceneRoot | 固定する土台 |
| Head | Scene | DefaultSceneRoot | 回転の中心 |
| Barrel | Static Mesh | Head | 正面へ伸びる砲身 |
Sceneコンポーネントは、位置や向きを持つ、見た目のない部品です。Headを回せば、その子のBarrelも一緒に回ります。砲身の中心ではなく、土台の上を旋回の中心にするために使います。
Baseには標準のCylinder、Barrelには標準のCubeを割り当てます。どちらも Engine/BasicShapes にあるメッシュで、見つからなければアセット選択欄でエンジンコンテンツを表示します。
「詳細」で、親から測った位置であるRelative Locationと、Scaleを次のように設定します。
| 名前 | Relative Location | Scale |
|---|---|---|
| Base | X=0 / Y=0 / Z=40 | X=1.2 / Y=1.2 / Z=0.8 |
| Head | X=0 / Y=0 / Z=80 | X=1 / Y=1 / Z=1 |
| Barrel | X=75 / Y=0 / Z=0 | X=1.5 / Y=0.3 / Z=0.3 |
回転はすべて0にします。HeadとメッシュのMobilityはMovable、メッシュ2つのSimulate Physicsはオフ、Collision PresetsはNoCollisionです。Movableは、ゲーム中に位置や向きを変更できる設定です。
Cubeの中心をHeadからX方向へ75cmずらし、長さを150cmにしたので、砲身が回転軸から前へ伸びます。前後が同じ形の立方体より、どちらを向いたかを見分けやすくなります。

レベルへBP_Turretを1つ置き、Actorの回転を0、Scaleを 1, 1, 1、Rootの高さを床へ合わせます。プレイヤーが周りを歩ける場所に置いてください。
2. プレイヤーがいるときだけ更新する
BP_Turretのイベントグラフで Get Player Pawn を置き、Player Index を0にします。この例では、1人目のプレイヤーが操作しているPawnを取得します。
そのReturn Valueを、白い実行ピンがある Is Valid のInput Objectへつなぎます。Event Tickの白い出力をIs Validの白い入力へつなぎ、Is Valid側の出口を後で使います。Is Not Valid側は空けます。
Is Validは、取得した相手を今使えるか確かめる処理です。プレイヤーがまだいない、削除された、といった場合は回転の更新へ進まないようにします。

3. プレイヤーを向く目標を作る
コンポーネント一覧からHeadをグラフへドラッグし、青い出力から Get World Location を作ります。これはHeadの、ワールド全体を基準にした位置です。
Get Player PawnのReturn Valueからは Get Actor Location を作ります。続けてFind Look at Rotationを置き、次をつなぎます。
| Find Look at Rotationの入力 | 接続元 |
|---|---|
| Start | HeadのGet World Location |
| Target | プレイヤーのGet Actor Location |
どちらもワールド基準の位置に揃えるのがポイントです。Startに使うのは床のRootではなく、砲塔の回転軸であるHeadです。

Find Look at RotationのReturn ValueからBreak Rotatorを作ります。そのYawだけをMake RotatorのYawへつなぎ、Make側のRollとPitchは0にします。

位置の取得、Find Look at Rotation、Break、Makeは、値を計算して返すノードです。白い実行線を順番につなぐのではなく、色付きのピンで値を渡します。
4. まずは、すぐ相手を向くところまで
Headの青い出力から Set World Rotation を作ります。TargetがHeadになっていることを確認し、New RotationへMake RotatorのReturn Valueを渡します。白い実行入力には、先ほどのIs Valid側の出口をつなぎます。
コンパイルしてPlayし、ゲーム画面をクリックして、砲塔の周りを歩いてください。土台は動かず、砲身だけがすぐプレイヤーを向けば成功です。ジャンプしても、砲身は上下に傾かず水平方向を向きます。
真上や真下では水平方向を決められないので、最初は土台の中心を通らず、少し離れて周囲を歩いて確かめてください。
5. 同じ砲塔へ補間を足す
Playを止め、Float変 数 TurnSpeed を作って、コンパイル後の既定値を 2 にします。
RInterp Toを置き、次の入力をつなぎます。
| 入力 | 接続元 |
|---|---|
| Current | Headから作るGet World Rotation |
| Target | 先ほどのMake RotatorのReturn Value |
| Delta Time | Event TickのDelta Seconds |
| Interp Speed | Get TurnSpeed |

今度は、Set World RotationのNew RotationへRInterp ToのReturn Valueをつなぎます。Make Rotatorから直接入れていた線を、この結果に差し替える形です。Is Validから来る白い実行線と、TargetのHeadはそのまま使います。

図のSet World Rotationは、手順4で作ったものです。新しく増やさず、New Rotationへの入力を差し替えてください。Sweepはオフのまま使います。
Get World Rotationは、この更新直前のHeadの向きを返します。そこから少し目標へ近づけ、その結果をHeadへ戻すので、次の更新でも続きから追いかけられます。
速さを変え、止まる原因も確かめる
コンパイルしてPlayし直し、同じように砲塔の周りを歩きます。今度は砲身が少し遅れて付いてきて、立ち止まると、こちらを向くまで徐々に差が小さくなります。
Playを止め、TurnSpeedの既定値を 10 に変えてもう一度試してください。2のときより素早く追うはずです。確認後は2へ戻します。
| 試すこと | 比べるところ |
|---|---|
| 同じくらいの距離で周囲を歩く | 2と10で、砲身の遅れ方が違うか |
| プレイヤーを止める | 目標へ近づくにつれて、旋回がゆっくりになるか |
| ジャンプする | 砲身は水平のままか |
| 砲塔の反対側へ回り込む | 土台を固定したまま、砲身だけが追うか |
「何秒で必ずぴたりと向く」とは決めていません。最初の角度差や更新間隔でも変わるため、同じように動かして追いかけ方を比較します。
Delta Timeを外すとどうなるか
Playを止め、RInterp ToのDelta Timeへ入る線を外し、値を0にします。TurnSpeedは2のままです。
コンパイルして再生すると、今度は砲身が目標へ近づかなくなります。「前の更新から0秒しかたっていない」と渡しているからです。確認後はPlayを止め、TickのDelta Secondsへつなぎ直し、回ることを再確認します。
一方、Delta Timeへ適当な正の定数を入れると、実際の経過時間ではなく、その定数を毎回使います。これが、更新回数によって追従の速さが変わる原因になります。未接続の0で進まない場合と、固定値で速さがずれる場合は分けて考えます。

また、Interp Speedの0は停止用ではありません。RInterp Toでは目標へ直接切り替わります。停止させたい場合は、条件でSet World Rotationへ進まないようにするなど、更新を止める仕組みを加えます。
うまくいかないとき
| 症状 | 確認するところ |
|---|---|
| 一瞬で目標を向く | SetへMake Rotatorを直接つないでいないか。Interp Speedが0、または大きすぎないか |
| 向きが変わらない | Is Valid側からSetへ白い線があるか。Delta TimeへDelta Secondsがつながっているか |
| 少し向いて、その位置で止まる | Currentに開始時の固定値を入れていないか。HeadのGet World Rotationを使っているか |
| 砲身が上下に傾く | Make RotatorのRoll/Pitchを0にし、Yawだけ渡しているか |
| 土台ごと回る | Set Actor Rotationを使っていないか。Set World RotationのTargetがHeadか |
| 砲身が横や後ろを向く | BarrelがHeadの子で、回転0・X方向へ伸びる形になっているか |
おまけ:先に知っておくと良いこと
WorldとRelativeは、どこを基準にした向きかが違います。 今回はワールド上の2点から目標を作るので、現在値もGet World Rotationで読み、Set World Rotationで反映しました。親から見て30度傾けたいなら、Set Relative Rotationが使えます。親が動くかどうかだけで選ばず、渡す向きの基準を揃えましょう。
Setは指定の向きへ変え、Addは今の向きへ足します。 回り続ける風車ならAddを使う方法もあります。その場合、毎フレーム1度と決めると更新回数で速さが変わります。「毎秒90度」なら、90にDelta Secondsを掛けた角度を、その更新で足すと考えます。
Quaternionも回転を表す形式です。 Roll・Pitch・Yawの3角度とは別の表し方で、複数の軸をまたぐ回転の合成や補間で使われます。今回の水平方向の砲塔は、Rotatorと専用ノードで作れます。自由に飛び回る機体やカメラの回転を扱う段階で、必要に応じて学べば十分です。
キャラクターの向きは、移動用の設定で作れる場合があります。 移動方向を向かせたいなら、Character Movement ComponentのOrient Rotation to MovementとRotation Rateも使えます。今回の方法は、土台から独立した砲塔や監視カメラのように、移動とは別に向きを制御したい場面で役立ちます。
旋回の速さは、ゲームの手応えにもつながります。 遅い砲塔なら裏へ回り込む余地が生まれ、速い砲塔なら正面を避け続けるのが難しくなります。発射条件や命中判定を加える前に、まずは追いかけ方だけを調整してみると、狙った違いを確かめやすくなります。
まとめ
Find Look at Rotationで目標の向きを作り、RInterp Toで今の向きから少し近づけ、Setで反映する。この役割を分けると、「向く方向がおかしい」のか「近づき方がおかしい」のかを切り分けやすくなります。
砲塔が動いたら、2と10のどちらが自分のゲームに合うか、同じ位置を歩いて比べてみてください。計算のノードを覚えるだけでなく、1つの数値で動きの印象が変わるところまで確かめられます。
参考:EpicのRInterp To、Lerp(Rotator)、Find Look at Rotation、Set World Rotation。