Happy My Life

日常とか技術とか

ゲームの数学 for UE4 ベクトル編

先日紹介したゲームアプリの数学 Unityで学ぶ基礎からシェーダーまでは、 3章はベクトルの話。ここからようやく3Dの話らしくなってきた、と思っているところ。

この本ではUnityでのベクトルの扱いについて書かれているので、このエントリーではUE4でのベクトルの扱いを書いてみる。

ベクトルとは

ベクトルとは数学的には「向きと大きさを表したもの」という定義になる。例えばボールが壁にぶつかって跳ねるといった古典力学の演算は、ベクトルを導入することで演算が楽になる(といっても、ゲームエンジンでは物理演算は物理エンジンが処理してくれるのだけど)。

ベクトルの定義の詳細は、こちらの解説が参考になるはず。

ベクトルの型

UE4には、Vector型とVector 2D型の2つがある。Vector型は(x, y, z)を扱い、Vector 2D型は(x, y)を扱う。

type-vector

type-vector2d

サポートされているBluePrintの関数の数はVector型に対応した物が圧倒的に多い(3次元を扱うので、そうなってしまって当たり前なのだが)。

で、Vector型の変数を使う目的は主に2つある。

  1. 本来のベクトルの値(向きと大きさ)を示す場合
  2. 3D空間での座標を示す場合

なので、コードを読みすすめる際には、「このVector型の変数に格納されている意味はどちらなのか?」を意識して読みすすめていかないと、意味が理解できないことになる。

Vector型での演算

まずはVector型の変数を対象として演算について取りあげてみる。

四則演算としては、Vector型同士で演算するモノと、Vector型とスカラー(整数、浮動小数)で演算するものがある。

Vector型同士の演算では、x要素同士、y要素同士、z要素同士で演算が行われ、Vector型とスカラーの演算では、スカラーの値がx、y、zのすべての要素に対して演算が行われる。

calc-vector

ベクトル成分の分解と生成

例えば、Vector型の変数で、xの値のみをセットしたいことがよくある。その場合は、BreakVectorを使ってVectorを分解して、値を変更して、MakeVectorで値を設定するとできる。Vector型の変数を生成したい場合も同様となる。

makevector

長さと正規化

ベクトルは長さも持つので、それが取得できるようになっている。取得はVectorLengthを行う。あと、正規化(ベクトルの長さを1にする処理)はnormalizeで行う。

正規化はよく利用する。というのも、例えば、キャラクターの向きをベクトルで持っている場合、向きが重要な意味を持ち、長さは無意味である。で、キャラクターをある速度で移動させたい場合は、キャラクターの向きの正規化されたベクトルを元に、移動速度(スカラー値)を掛けて移動量を算出する、といった処理を行う(ってのをUE4のサンプルのどこかででも見かけたけど、はてどこだっけ…)。

SS_150930_1612_00

内積と外積

内積(dot product)と外積(cross product)もサポートされている。このあたりは、一般的な3D演算ライブラリでも必ずといっていいほどサポートされている機能でもある。内積と外積は基礎の基礎編その1 内積と外積の使い方あたりを参考にどうぞ。

個人的によく使うポイントとしては、内積はベクトル同士のなす角を取得する場合、外積は平面の法線ベクトルを求める場合に使った。検索する際には、内積 = dot product、外積 = cross productと単語を覚えておくと、後々幸せになれる。

dotproduct

向きの取得

UE4では、Get Forward Vector、Get Right Vectorなどの、正規化された方向のベクトルを取得する関数が用意されている。

例えば、Get Forward Vectorでは回転量を指定しない場合、(1, 0, 0)が返ってくる。「Get Forward Vectorなんて使わずに、(1, 0, 0)を返せば良いじゃん」って話でもあるのだけど、Get Forward Vectorから取得したほうが「あ、前進するためのベクトルを取得するのだな」と分かってよい、という事なんだと思う。たぶん。

forwardvector

回転

ベクトル(向き)を回転させたい、ということもよくある。そんな時は、Rotate Vectorを使う。ちなみにUnroate Vectorは、Rotate Vectorの逆回転版らしい。Unrotateってのがなにやら紛らわしいので注意(Inverseなんとか、の方が分かりやすいように思える)。

ベクトルを回転させるには、"回転行列 x ベクトル"と演算するのだが、Rotate Vectorだと行列すら出てこないので理解しやすいんじゃないかと。

rotatevector

鏡面反射

光の鏡面反射を実現するためのブループリントの関数も用意されている。入力するベクトルと、面を示す法線を入力することで、その面に反射した結果のベクトルが取得できるようになっている。今回のぶちコンでは大活躍している関数なんではなかろうかと思っているのだが。

mirrorvector

Vector 2Dについて

Vector 2Dを対象とした処理ももちろん用意されている。

といっても、処理できる内容については、ここまで解説したものばかりなので、詳細は省く。

vector2d