あちこち検索すると GetActorLocation に Timeline (float) の値を加えて SetActorLocation にセットすることでアクターを動かす方法が出てくるけど、その方法だとしばらく往復運動させていると位置がずれてしまう。ここでは、ずれないで往復運動する方法をメモしておく。
環境
- Windows 10 Home
- Unreal Engine 4.24
準備
とりあえず ThirdPerson テンプレートで作成したプロジェクトを使って説明してみる。ThirdPerson テンプレートでなくても、同じことはできる。
設定はデフォルトのままで、プロジェクト名は MotionSample としてみる。
最初に配置されている CubeMesh を上下に動くように改造することにする。
方針
- CubeMesh の初期位置を Vector 変数に保存する。
- TimeLine で往復運動をする物体の位置情報を作る。
- 初期位置に Timeline で生成した数値を加えることで、物体の現在位置を算出する。
初期位置に、Timeline で位置の差分を加えて現在位置を算出することで、Timeline の値が 0 のときには正確に初期位置に戻るようになる。
手順
CubeMesh を選んだ状態で、右側にある「ブループリント/スクリプト編集」を押す。
「ブループリントを作成」を押す。ブループリント名はデフォルトのままでいい。
ブループリントのエディタの「イベントグラフ」のタブを開く。
右クリックして、Timeline と入力する。
メニューの一番下に出てくる「タイムラインを追加する」を選ぶ。公式サイトとかの説明だと、英語のメニューになっていて Add Timeline を選べと書いてあったりするので、つい Timeline という文字列を探してしまうかもしれないけど、ここだけ微妙に日本語化されてるのよね。
タイムラインが配置されたら、ダブルクリックしてタイムラインエディタを出す。
「フロートトラックを追加」を押す。ベクタートラックを追加するのでもできるけど、ここでフロートトラックでやっておく。
エディタの画面で、Shift を押しながら左クリックすると、グラフの点を追加できる。
こんな感じに、0の点から始まって0に戻るような線を描く。点を選択した状態で、上にある「時間」「値」のところに数値を直接入力することもできる。
上にある「ループ」のところにチェックを入れておく。これにチェックが入ってないと、一往復しただけで動かなくなる。
グラフを描画してからイベントグラフに戻ると、タイムラインの右下に「新規Track0」という緑色のポチが増えているはず(名前は多少違うかもしれない)。こうなってなければ何か操作をまちがっている(かも)。あとは、最初の方針に従ってグラフを作る。
初期位置を変数に保存する
左下あたりにある「変数」の横の「+」を押して、初期位置を入れる Vector 型の変数を作る。名前は DefaultPosition としてみた。
右側の「詳細」の欄で、変数の型を Vector にしておく。
変数をイベントグラフ内にドラッグドロップする。選択肢が出るので、Set DefaultPosition のほうを選ぶ。
イベントグラフで右クリックして、GetAct くらい入力して GetActorLocation を探して選ぶ。
イベントグラフ中に配置したら、下の図のように接続していく。BeginPlay に「セット」をつなぎ、GetActorLocation を値の入力とすることで、アプリ開始時点でのアクターの初期位置を DefaultLocation の変数にセットすることができる。
タイムラインより右側のイベントグラフも、下の図のように作る。
- Default Position の黄色い箱は、変数の Default Position をイベントグラフにドラッグドロップして "Get DefaultPosition" を選ぶことで置ける。
- "+" の黄色い箱は、右クリックメニューから "Add" と入力して "vector + vector" という項目を探して置く。
- Speed の緑色の箱は、先に左側の「変数」のところで+を押して Speed という名前で作成しておく。右側の「詳細」で 「変数の型」を float にしておく。変数を作ったら、イベントグラフにドラッグドロップして Get Speed を選ぶことで置ける。
- 右下の Make Vector は、右クリックメニューで "Make Vector" と入力して探して置く。
- 中央下の "X" は、右クリックメニューで "mul" と入力して、Multiply の float * float を選ぶ。
最後に、メインのウィンドウで CubeMesh を選んで「トランスフォーム」の下にある「可動性」のところを「ムーバブル」に変更しておく。この変更をしないと、プログラムを書いてもアクターが動いてくれない。
これで動くはず
オブジェクトの初期位置をベースにして、時間が経過したときに Timeline のその時刻の値を、オブジェクトの位置の z 座標にセットするようにしている。初期位置をベースにしているので、Timeline の値が 0 になれば、必ず初期位置に戻る。これによって、往復運動をするごとに位置がずれていくことは防げる。
位置がだんだんずれる方法
検索でよく見つかる、位置がだんだんずれていく方法も参考までに載せておく。
初期位置を保存する変数を使わず、GetActorLocation で取得した位置ベクトルに、直接タイムラインの値を加える。つまり、タイムラインの値を z 軸の移動速度のように使う。加算による誤差が蓄積いしていくため、時間が経過するに従って、オブジェクトが動く z の範囲がだんだんずれていく。
動き方は、ずれない方法とは同じにならず、速度 0 の状態から次第に加速していって、途中からは次第に減速して 0 になるという、見た目には自然な動きになる。これは、タイムラインの値が z 軸の位置ではなく、速度として使われるためである。
ずれない方法でも同じような動きにするためには、タイムラインの線をサインカーブ状にすればよい。