読者です 読者をやめる 読者になる 読者になる

お茶漬けびより

学んだことを整理する場所です。主に、C++, Unreal Engine 4 (UE4) を扱います。

アクターを移動させる Blueprint

移動系のBleuprint(BP)を調べたのでまとめます。
といっても基本的な内容なので、大したものではないのですが。
 
アクターを移動させるためのBPはいろいろあると思います。
今回は、以下を調べました。
  • SetActorLocation
  • SetActorRelativeLocation
  • AddActorWorldOffset
  • AddActorLocalOffset
ここでは、SetActorLocation と SetActorRelativeLocation のことをまとめて、Location 系と呼び、AddActorWorldOffset と AddActorLocalOffset のことをまとめて、Offset 系と呼ぶことにします。 

Location 系

・SetActorLocation 

Input
Target(Actor Reference)
移動させたいアクター(以下ターゲット)を指定
New Location(Vector
世界座標の位置を指定。
Sweep(Boolean)
True のとき有効。ターゲットが物体にぶつかるとターゲットは停止する。
Teleport(Boolean)

指定した位置に瞬間移動するようになる

 
Output
Sweep Hit Result(Hit Result Structure)
Sweep を有効にしているときに何かにぶつかると Hit Result Structureとして返す
Return Value
移動に成功したとき True を返す。Sweep が無効のときは必ず True になる(はず)

詳細
New Location で指定した世界座標(ワールド座標、絶対座標)の位置に物体を動かします。Sweep を有効にすると現在位置から New Location の直線状に物体があるとその物体の手前で止まります。
Sweep についてはいくつか注意する点があります。
  • Sweep の機能は、ターゲットとぶつかる対象の両方が、Collison のオブジェクト応答でブロックしているとき機能する。
  • ターゲットは、ルートコンポーネントコリジョンの設定(オブジェクト応答)をしないと機能しない。
  • 注意ではないが、「オーバーラップイベントを発行させる」は有効にしなくてよい。
2つ目のルートコンポーネントコリジョンの設定をする話は、Sweep の仕様というよりもコリジョンの問題っぽい?*1
Teleport は、ルートコンポーネントについている別のコンポーネント側に移動速度を反映させないようにするようです*2

・SetActorRelativeLocation

Input
Target(Actor Reference)
移動させたいアクター(以下ターゲット)を指定
New Relative Location(Vector
アウトライナ上で親子関係のある、親を中心(0, 0, 0)とした座標位置を指定。
Sweep(Boolean)
True のとき有効。ターゲットが物体にぶつかるとターゲットは停止する。
 
Output
Sweep Hit Result(Hit Result Structure)
Sweep を有効にしているときに何かにぶつかると Hit Result Structure として返す
詳細
機能としてはほとんど同じですが、移動するときの基準となる座標が違います。
SetActorLocation のときは世界座標でしたが、SetActorRelativeLocation の場合は、親の位置を中心(0, 0, 0)とした相対座標(ローカル座標)になります。ここでいう親というのは、アウトライナ上の親子関係のことです。親子関係は、アクタを別のアクタにドラッグすること(アタッチ)で作れます。この場合、ドラッグ側のアクタがドラッグ先のアクタの子になります*3

Offset 系 

・AddActorWorldOffset

Input
Target(Actor Reference)
移動させたいアクター(以下ターゲット)を指定
Delta Location(Vector
ターゲットの現在位置から Delta Location だけ世界座標を軸に移動する。
Sweep(Boolean)
True のとき有効。ターゲットが物体にぶつかるとターゲットは停止する。
Teleport(Boolean)
指定した位置に瞬間移動するようになる。

Output
Sweep Hit Result(Hit Result Structure)
Sweep を有効にしているときに何かにぶつかると Hit Result Structure として返す


・AddActorLocalOffset

Input
Target(Actor Reference)
移動させたいアクター(以下ターゲット)を指定
Delta Location(Vector
ターゲットの現在位置から Delta Location だけ相対座標を軸に移動する。
Sweep(Boolean)
True のとき有効。ターゲットが物体にぶつかるとターゲットは停止する。
Teleport(Boolean)
指定した位置に瞬間移動するようになる。

Output
Sweep Hit Result(Hit Result Structure)
Sweep を有効にしているときに何かにぶつかるとHit Result Structure として返す
詳細
二つをまとめて紹介したほうが、分かりやすいと思ったので同時に説明します。
まずこの二つの名前には Offset というのが付いていますが、Offset とは何でしょうか?
上記の内容が分かりやすかったので、載せておきます。これによると Offset は基準の位置からのズレということです。つまり Offset 系は、ターゲットの位置を基準とした位置から Delta Location の分だけズラすということでしょう。ということは、これを使えばわざわざ Location 系を使うときに、(現在位置+移動量)の値を New Location にする必要はなさそうです。 
では、 Local と World の違いは何でしょうか。これは憶測ですが基準となる軸のことを指していると思っています。つまり、Local の場合はローカル座標(相対座標)を軸とした移動で、World は世界座標を軸とした移動になるということです。
例えば、以下の図のようなローカル座標があるとします。

f:id:pickles-ochazuke:20170104032751j:plain

このローカル座標は、ターゲット自身の座標です。この状態で AddActorLocalOffset の Delta Location に(0, 10, 0)の Vector を設定すると、Y軸方向に 10 進みます。これは下図のように前方に進んでいるように見えます。

f:id:pickles-ochazuke:20170104032849j:plain

では、この Local 座標の Z 軸を 90 度回転します。すると下図のようになりました。

f:id:pickles-ochazuke:20170104032917j:plain

この状態で先ほどと同じように移動させてみましょう。Y 軸方向に 10 進みます。これは、下図のようになります。

f:id:pickles-ochazuke:20170104032938j:plain

つまり、 AddActorLocalOffset はターゲットが回転すると、その影響を受けて移動をするということです。
逆に AddActorWorldOffset はターゲットが回転をしても影響ありません。ローカル座標ではなく世界座標を軸に移動しているからです。もちろん世界座標が回転をすれば、AddActorWorldOffset は影響を受けます。この場合 AddActorLocalOffset は影響を受けないはずです(憶測です……)。
また、ターゲットが親子関係を持っている場合、AddActorLocalOffset はターゲット自身の軸と親の軸、両方の軸を見ている(合わせている?)ようです。ややこしいのですが、例えば親が Z 軸右に 90 度回転していて、ターゲット自身も Z 軸右に 90 度回転している場合、二つの回転を合わせた Z 軸 180 度回転した軸を基準に移動するようになります。
 
以上、Offset 系の説明でした。長々と説明しましたが、説明を読むよりも実際にBPを組んでみたほうが実感が湧くと思います。自分もこの記事を書きながら実行をするなかでいくつか疑問点が出て、実際に試して疑問を解消したので手で動かすことをオススメします(ただ手を動かすのではなく、考えて動かすこと)。
 
最後に、とても参考になった記事
以上です。初めての BP の記事を書いたので間違っているところがあるかもしれません。もし間違いに気付いた方がいらっしゃれば、コメントで指摘していただけると嬉しいです。