LoginSignup
3
1

More than 3 years have passed since last update.

【UE4】エモノを食って飛び去るドラゴン/第13回UE4ぷちコン進捗 - 2020/03/22

Posted at

株式会社ヒストリアさん主催の第13回UE4ぷちコンの作業進捗。

作業をしながらおやつを食べすぎて、晩飯はまだ欲しくない。
…ので、進捗記事を書いておこう。(これが終わったら晩飯にしよう)

引き続き、敵となるドラゴンを作っている。
前回の飛来の続きとなる、エモノに食らいついて飛び去るような挙動を作成した。

例によって、本プロジェクトとは別の、実験用のプロジェクトで作っている。

こんな感じになった

20200322_2017.gif

  • 【左手前】標準位置となるであろう距離での食らいつき実験。
  • 【中央】横に振ったら変に見えるかどうかの実験。(アリだと判断)
  • 【右奥】これは遠すぎるだろう、という距離での実験(さすがにナシ。残像見えてるし)

まあ、動きが速すぎて、どれもズルい感じもしなくもない。

ゲーム本編ではドラゴンは1匹の予定。

食らいつきについて

食らいつき判定がでたら(今回はゲームパッドのボタンを押したら)、まずはエモノの位置から逆算した、食らいつき Transform を算出する。
これが昨日ハマっていた、Construction Script でのあれこれである。結局は、愚直に Tick を回して Print String でログに計算結果を出して、その数値をコピペして使っている。

次のフレームからは、その Transform に向かってホーミング。
Ease ノードの Ease Out を使用。(出だしが早く、だんだんゆっくりになる挙動)

20200322_2036.png

この Ease ノードの使い方、おそらく誰もやっていないだろう的なトリッキーな方法。
通常、Alpha は変数で持っておいて、Tick か何かで

Alpha = Clamp(Alpha + AlphaSpeed * DeltaSeconds, 0.0f, 1.0f);

的な計算をするはず。一方、このやり方は、

Alpha = DeltaSeconds / ConvergeSeconds;

…とただDeltaSecondsを定数ConvergeSecondsで割っているだけで、Ease用の変数 Alphaを持つ必要がない。ちなみに、このConvergeSecondsは「収束するまでの秒数」の意。つまり、ConvergeSeconds の秒数で目標値に追いつくことになる。

このアイデアは、大昔の固定フレームレートの時代にやっていた

void SomeObject::Tick()
{
    CurrentValue = Lerp(CurrentValue, TargetValue, 0.9f);
}

みたいな、毎フレーム 90% の割合で目標値(TargetValue)に近づけるやり方=残り距離の10%ずつ近づけるやり方を、可変フレームレートの世界に持ち込もうとして作ったもの。

大雑把には:

  • 毎フレーム 0.9 倍というやり方は、等比級数と同じ挙動をするよね。
  • 等比級数の極限をとると、exponential の曲線になるよね。
  • 極限をとるということは、連続系(=可変フレームレート)の世界で使える式になるよね。
  • そういえば、Ease は exponential 曲線だよね。
  • まじめに数式を解くのが面倒なので、Ease 使えばいいんじゃね?

という考えで編み出したもの。私の好みの挙動をするので多用している。

【注意】全く厳密な計算ではないので注意。似ているから Ease を使っているだけ。なので、ConvergeSeconds で指定した時間でちゃんと収束するわけでもないし、フレーム落ちの影響を受けたりしてしまう。とはいえ、可変フレームレートの世界で毎フレーム 0.9 を掛けるようなやり方よりは、フレーム落ち時の暴れ方は穏やか。

もし、フレームが安定しないアプリになってしまったり、ヒッチが多くなってしまったりしたら、あらかじめ DeltaSeconds = Clamp(DeltaSeconds, 1/90, 1/45) などして、例えば DeltaSeconds = 1.00(秒) みたいな極端な値にならないように誤魔化すのも手。

咥えて(くわえて)連れ去る周り

噛みつきアニメーションに「BiteAlpha(食いつきアルファ)」のカーブを用意。

20200322_2100.png

0なら咥えてない、1なら咥えている、を表すためのもの。
これで、エモノの Transform を、現在の位置から、口の中の位置まで Lerp している。
で、一度咥えたら(1に達したら)、

  • エモノActorを消して、ドラゴンがあらかじめ持っているエモノコンポーネント(=Skeletal Mesh Component) を表示する。
  • あとは、ずっと口の中の Transform にする。

飛び去る

これは単純にアニメーションを再生しながら、World Up 方向に Add Force しているだけ。
一定の高度に達したら Destroy Actor する。

とりあえず、現状はこんな感じ。
…さて、晩飯に取り掛かるとするか。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1