LoginSignup
1
0

More than 3 years have passed since last update.

【UE4】ConstructionScriptでのGetSocketTransformがおかしい?(BP)+フレームレートの取得(C++)/第13回UE4ぷちコン進捗 - 2020/03/21

Last updated at Posted at 2020-03-22

株式会社ヒストリアさん主催の第13回UE4ぷちコンの作業進捗。
昨夜ハマったネタの備忘録として。

ConstructionScript × GetSocketTransform

image.png

上は、コンストラクションスクリプト上で、ドラゴンの Head ボーンの World Transform を取得するノードグラフ。

Draw Debug Coordinate Cross は、ただ単に座標軸を書くためのもの。
UE4 標準の Draw Debug Coordinate System もよく使うが、マイナス軸の表示も欲しいときはこういうのを使っている。

この結果、エディタのビューポートに表示される絵はこうなる:

20200322_1210.png

頭と全然違う位置に座標軸のデバッグ表示が出てしまっている。

ドラゴンの体を通るピンクのラインは、ビューポート内の Show メニューの Developer > Bones を ON にしたもの。

おおむね昨日一日、この問題で悶絶していた。
もともとは、頭(≒顎)に対する餌の位置を探していたので、逆行列の計算とかがアレコレ入っていて、掛け算の順番を間違ったか?とか、World Spaceじゃなくて、Component Spaceなのか?とか、そっちの方を必死に追いかけてしまっていた。

ふと、思い立って、Tickでもデバッグ表示してみたのがこちら:

20200322_1211.png

あってんじゃん!

ボーン表示はコンソールコマンド show Bones

ということで、今のところ、Construction Script で Get Socket Transform をすると、正しくない値が返ってくる可能性があるかもしれません。実行中の Get Socket Transform は正しい値を返します。(UE4.24.3)

例えば、グレイマンでは正しく出るのではないかとか、Get Socket Location ならどうなのか、など、他のシチュエーションでの追加調査をする余裕はないので、このまま放置します。すみません。(…ぷちコン締め切りまで1週間!)

ざっくり何をやったかだけ列挙すると:

  • Construction Script での動作
  • Skeletal Mesh Component (=ドラゴン) は、Yaw回転が-90度で、2倍のスケール
  • Skeletal Mesh Component の Override Animation Data で、エディタ上で表示するアニメーションとフレーム番号を指定。
    • 【追記】IsPlaying = True, PlayRate = 0.0 でも、IsPlaying = False, PlayRate = 1.0 でも、状況は変わらず。
  • その後、Get Socket Transform で頭ボーンの Transform を取得

こういう流れでやっています。

AnimSequenceからフレームレートなどを取得する

Blueprintでは取得できない、アニメーションシーケンスの総フレーム数、フレームレートなどについて。
もう取れないものだとずっと諦めていたのだが、今更ながら、C++でサクっと取得できることに気づいた。

C++ で Blueprint Function Library を作って、一気に便利に取得するようにした例:

GetAnimFrameInfo()
void UMyBlueprintFunctionLibrary::GetAnimFrameInfo(UAnimSequence* InAnimSequence,
    bool& OutSuccess, int& OutNumFrames, float& OutPlayLength, float& OutFrameRate)
{
    if (!InAnimSequence)
    {
        UE_LOG(LogMyLibrary, Error, TEXT("GetAnimFrameInfo()  InAnimSequence must not be a nullptr."));
        OutSuccess = false;
        return;
    }

    OutSuccess = true;
    OutNumFrames = InAnimSequence->GetNumberOfFrames();
    OutPlayLength = InAnimSequence->GetPlayLength();
    OutFrameRate = InAnimSequence->GetFrameRate();
}

【注意】自作関数GetAnimFrameInfo()の第一引数の型がconst UAnimSequence*ではなく、UAnimSequence*なのは、GetPlayLength()だけconst関数ではないため。(泣く泣く)

ついでに便利そうな関数も

後日談 (2020/05/01)
UAnimSequenceBase::GetTimeAtFrame() も UAnimSequence::GetFrameAtTime() も、WITH_EDITOR 関数だった。
パッケージビルドをするとビルドエラーが出る。
これらは、Editor 専用モジュールでしか使ってはいけない。

フレーム番号と時間(秒)の変換

#if WITH_EDITOR

float UMyBlueprintFunctionLibrary::GetAnimTimeAtFrame(const UAnimSequence* InAnimSequence, int InFrame)
{
    if (!InAnimSequence)
    {
        UE_LOG(LogMyLibrary, Error, TEXT("GetAnimTimeAtFrame()  InAnimSequence must not be a nullptr."));
        return 0.0f;
    }

    return InAnimSequence->GetTimeAtFrame(InFrame);
}


int UMyBlueprintFunctionLibrary::GetAnimFrameAtTime(const UAnimSequence* InAnimSequence, float InTime)
{
    if (!InAnimSequence)
    {
        UE_LOG(LogMyLibrary, Error, TEXT("GetAnimFrameAtTime()  InAnimSequence must not be a nullptr."));
        return 0.0f;
    }

    return InAnimSequence->GetFrameAtTime(InTime);
}

#endif // WITH_EDITOR

こちらはconst UAnimSequence*型で行ける。

1
0
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
1
0