ゲーム作りが大好きな人のブログ

ゲームを作るのが大好きな人のブログ。UE4とBlender、MAYA(LT)、3DCoatを使用しています!

【UMG】【C++】独自UMGオブジェクトを作る

UE4.22.3で検証しています
C++の使用が必須となります
※ 間違えていたらごめんなさい

前々回からの続きです。
toofu0.hatenablog.com

今回は独自UMGオブジェクトのお話です。
※ 最後にBlueprintでテキストブロックのサイズを1フレ目から取る方法を書いてます!


独自UMGオブジェクトってなんやねん

まず、こちらを見てほしい。
UMGのパレット画面です。
f:id:toofu0:20190924004905p:plain

My Text Block……ドチラ様ですか……?
これが独自UMGオブジェクト(名称は自分が勝手につけてます)です。
C++でTextBlockオブジェクトを継承したクラスを作ると
そのクラスがUMGのオブジェクトとして追加されます。

こういったオリジナルのUMGオブジェクトはBPでも作る事が出来ますが
アクセスできる変数・関数が制限されている為、効率的とは言えないと思います。

それではソースコードを見ていきましょう。

ソースコード

MyTextBlock.h
#pragma once

#include "CoreMinimal.h"
#include "Components/TextBlock.h"
#include "MyTextBlock.generated.h"


UCLASS()
class UMyTextBlock : public UTextBlock
{
	GENERATED_BODY()

	UMyTextBlock(){}

	//	即時にテキストのサイズを取得
	UFUNCTION(BlueprintPure)
	FVector2D GetTextSize();
};
MyTextBlock.cpp
#include "MyTextBlock.h"

FVector2D UMyTextBlock::GetTextSize()
{
	if (MyTextBlock.IsValid())
	{
		return MyTextBlock->ComputeDesiredSize(1.0f);
	}

	return FVector2D::ZeroVector;
}

たったこんだけ。ファイル名間違えないようにね。
C++でUMGを使った事がないプロジェクトの場合
これだけだとビルドエラーになります。
理由はUMGモジュールが依存関係に含まれてないからです。

以下のページを参考にしてUMGのモジュールを追加してください。
このコードだけで言えば"Slate", "SlateCore"は不要なのでそこは無視してOKです。
docs.unrealengine.com


というわけで完成

これでビルドして実行すればMyTextBlockが追加され、使用可能になります。

1フレでTextBlockのサイズを取得するには……

まずMyTextBlockをUMGに配置しましょう。
そして、上のコードまんまであればC++で定義したGetTextSizeが使えるようになっています。
f:id:toofu0:20190924014113p:plain

それでは本当にサイズが取得できるか実験もしてみましょう。
BPでこんな感じにノードを組んで……
f:id:toofu0:20190924014152p:plain

これでゲームを実行すると……
f:id:toofu0:20190924014209p:plain

出来てる出来てる!
Desired Size は0しか取れていませんが、GetTextSizeは取れていますね。
無事完成です。

余談

・ここで取れる値はあくまでテキストデータのサイズであり
 キャンバスのサイズではありません。そこを間違えないようにお気をつけください。
・厳密にはDesired Sizeの戻り値とは違います。
 Desired Sizeは多分dpiスケールかレターボックス関連の値を最終的に掛けていると思います。
 ちょっとそこまで調べる時間がなかった。