【UE5】UFUNCTION【C++】

実際につくってみて、学んだこと試したこと気づいたことなどをまとめています。

UFUNCTION SPECIFIERS

BlueprintCallable

左右に実行ピンを持った、青いノードをつくる。

整数をスクリーン上に表示

ヘッダーファイルの関数名にマウスを合わせ、右クリックすることで選択できる。
ソースファイルに処理を作成するためのテンプレートを自動的に作ってくれる。

右クリック>Quick Actions and Refactorings(VA)

たぶん、有料ソフトのVissual Assistを使っていないと無理。

MyActor.h

public:
UFUNCTION(BlueprintCallable, Category="Actor Functions")
void PrintInt(int32 Value);

MyActor.cpp

void AMyActor::PrintInt(int32 value)
{
	UKismetSystemLibrary::PrintString(this, FString::Printf(TEXT("Print Int %d"), value), true, true, FColor::Red, 10.0f);
}

結果

BlueprintPure

実行ピンがない、緑色のノードをつくる。

実行ピンのないノードには2種類の作り方がある

BlueprintCallableの方はSelf Pinがあるが、META TAGで消せる。

実行ピンのないノードBlueprintPureとBlueprintCallable+const。

MyActor.h

UFUNCTION(BlueprintPure, Category="Actor Functions")
	int32 AdditionPure(int32 ValA, int32 ValB);

	UFUNCTION(BlueprintCallable, Category="Actor Functions")
	int32 MultiplicationPure(int32 ValA, int32 ValB) const;

MyActor.cpp

int32 AMyActor::AdditionPure(int32 ValA, int32 ValB)
{
	return ValA + ValB;
}

int32 AMyActor::MultiplicationPure(int32 ValA, int32 ValB) const
{
	return ValA * ValB;
}

結果

BlueprintImplementableEvent

C++では処理を実装できない。
C++によってイベントが呼び出される。
カスタムイベントのようにふるまう。

Create Implement Eventでイベントを実装しようとしたら、下のポップアップがでた。C++では処理を実装できないので。

👇分かりやすい。分かった気になれた。BlueprintImplementEventは、オーバーライドと関係があるらしい。

https://wa3.i-3-i.info/word138.html


①Event Graphで右クリック。良くやるやつ。

右クリック

②FUNCTIONSの右のプラスボタンにホバーすると、Overrideのプルダウンメニューが現れる。

Override

例1:キルZ時(落下したとき)にアクターを破壊。

クラス名を右クリック>Quick Actions and Refactorings>Implement Virtual Method
Visual Assist(有料)の機能。クラスで使える関数を呼び出せる。

↓検索して、チェックをいれてOK。

↓自動的にコードが作成される。

ヘッダファイル

ソースファイル

FellOutOfWorldの関数自体は、Implement Virtual Methodをつかったら簡単にコードを記述できる。Visual Assistなどがなくても、直接打てば問題ない。
MyActor.h

public:
void FellOutOfWorld(const class UDamageType& dmgType) override;

UFUNCTION(BlueprintImplementableEvent, Category = "Actor Functions")
void OnFellOutOfWorld();

MyActor.cpp

void AMyActor::FellOutOfWorld(const class UDamageType& dmgType)
{
	OnFellOutOfWorld();
}

例2:プレイ開始時、設定した数値(27)をスクリーン上に表示。

MyActor.h

UFUNCTION(BlueprintImplementableEvent, Category = "Actor Functions")
void IntOutput(int32 Val);

MyActor.cpp

void AMyActor::BeginPlay()
{
	Super::BeginPlay();
	IntOutput(27);
}

結果

関数の戻り値の型を変更する。

bool

float

変数の型を与えると、カスタムイベントではなく、関数になる。
👇boolの場合

UFUNCTION(BlueprintImplementableEvent, Category = "Actor Functions")
bool IntOutput(int32 Val);

設定した戻り値をどのように使えるかは分からない。イベントグラフに関数を配置できなかったので。C++で使うのかな。

BlueprintNativeEvent

準備

シーンコンポーネントと、スタティックメッシュの追加

今の僕の理解としては下記。
・クラスと同じ名前の関数
・Event BeginPlayより先に実行される
(参考)

AMyActor::AMyActor()
{

Scene = CreateDefaultSubobject<USceneComponent>(TEXT("Scene"));
CubeMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("StaticMesh"));

Scene->SetupAttachment(GetRootComponent());
CubeMesh->SetupAttachment(Scene);

}


👇よくお世話になっているサイト様による解説

コンストラクタとは|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典
「コンストラクタ」の意味を何となく説明しています。

MyActor.h

protected:

UPROPERTY(VisibleAnywhere,BlueprintReadOnly, Category="Components")
USceneComponent* Scene;

UPROPERTY(VisibleAnywhere,BlueprintReadOnly, Category="Components")
UStaticMeshComponent* CubeMesh;

MyActor.cpp(コンストラクタに記述)

AMyActor::AMyActor()
{

Scene = CreateDefaultSubobject<USceneComponent>(TEXT("Scene"));
CubeMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("StaticMesh"));

Scene->SetupAttachment(GetRootComponent());
CubeMesh->SetupAttachment(Scene);

}

1.親にしたいC++クラスを右クリック。
2.Create Blueprint class based on “親にしたいC++クラス”を選択。

Content Drawerで右クリック>Blueprint Classを選択。
Parent ClassをAll CLASSESから検索して、親にしたいC++クラスを選ぶ。

左右に往復移動

MyActor.h
(protected)

UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "MyActor")
bool bIsRight;

UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "MyActor")
float LeftLimit;

UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "MyActor")
float RightLimit;

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyActor")
float Length;

UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "MyActor")
float CurrentX;

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyActor", meta = (Tooltip = "the speed of the actor", ClampMin = "20", ClampMax = "100"))
float Speed;

MyActor.cpp
(コンストラクタ)

Speed = 50;
Length = 200;

(BeginPlay)


const FVector Location = GetActorLocation();
CurrentX = Location.X;
LeftLimit = Location.X;
RightLimit = Location.X + Length;
bIsRight = true;

(Tick)


Super::Tick(DeltaTime);

const float Val = DeltaTime * Speed;

if (bIsRight)
{
	CurrentX = CurrentX + Val;
}
else
{
	CurrentX = CurrentX - Val;
}

FVector Location = GetActorLocation();
Location.X = CurrentX;

SetActorLocation(Location);

if (CurrentX > RightLimit)
{
	bIsRight = false;
}
else if (CurrentX < LeftLimit)
{
	bIsRight = true;
}

BlueprintNativeEvent

・Blueprintで処理を上書き(オーバーライド)できるが、もともと処理を持っている。
・もともと持っている処理をここではImplementation Functionと呼ぶ。
・Implementation Functionは、関数名の末尾に”_implementation”とつけた関数で追加できる。
・オーバーライドされていなければ、Implementation Functionが実行される。
・オーバーライドされているとき、Implementation Functionを実行するにはParent Functionを作成して処理の中に追加すればいい。

右クリック>Add call to parent function

(注意)
Native Event(My Destroy)を作成して、他のノードにつなげずに実行したらクラッシュした。
他のノードに繋げれば問題なく実行され、Parent Functionに繋げなくても問題はなかった。
Native Eventを作成しなければ、Parent Functionの処理だけを実行。

(関連)
子のブループリントを作ったとき、BeginPlayなどにデフォルトで接続されているノードも確かParent Function。
作り方が分からなかったので、親の処理を作りなおしていた。BeginPlayで右クリックすればParent Functionを作成できる。

・親が持っている関数。
・Implementation Functionで処理を追加(or上書き?)できる。
・Implementation Functionを作るには、BlueprintNativeEventにする。

正しいかどうか試してはいないので、いつか試す。
BlueprintNativeEventではなくても、Parent Function自体は作れた。

移動してから消える

Blueprintは何も記述しないで大丈夫。

👇何も記述しなければ、この処理が実行される。

MyActor.h

UFUNCTION(BlueprintNativeEvent, Category="Actor Functions")
void MyDestroy();
void MyDestroy_Implementation();

MyActor.cpp
MyDestroy_Implementation

void AMyActor::MyDestroy_Implementation()
{
	this->Destroy();
}

Tick(右に移動した後の処理に追記)

if (CurrentX > RightLimit)
{
	bIsRight = false;
	MyDestroy();
}

移動して落下してから消える

👇Parent Functionとの間に処理を挟むことができる。Parent Functionは入れなくても大丈夫。
ただしNative Event(My Destroy)を作って、なにも処理を書かないとクラッシュする。

META TAG

記述の型

DisplayName="名前"

自作の関数名をDestroyにするとクラッシュした。C++において、もともと設定されている関数名だからだと思う。関数名ではなくDisplayNameをDestroyと設定するのなら問題ない。

MyActor.h

UFUNCTION(BlueprintNativeEvent, Category="Actor Functions", meta=(DisplayName="Destroy"))
void MyDestroy();
void MyDestroy_Implementation();

関数の名前MyDestroyではなく、DisplayNameが表示される。

記述の型

ToolTip="説明"

ノードにマウスホバーした際にでる説明を記述できる。

MyActor.h

UFUNCTION(BlueprintNativeEvent, Category="Actor Functions", meta=(DisplayName="Destroy", ToolTip="The actor is destroyed when it reach the right limit."))
void MyDestroy();
void MyDestroy_Implementation();

昔作ったノードなんてすぐに忘れそうだから、ちゃんと説明を書いておこう。英語は適当。

記述の型

ShortToolTip="何か"

マウスホバーで表示されるわけではないらしい。いつどこで表示されるのか知りたい。見つかったら追記します。

MyActor.h

UFUNCTION(BlueprintCallable, Category="Actor Functions", meta=(HideSelfPin="true", ShortToolTip="Print the integer to the screen."))
void PrintInt(int32 Value);

ちなみにTEXT(” “)をつかって日本語を表示させようとしたが、コンパイルでエラーが出て無理だった。

記述の型

HideSelfPin="true"

Selfピンを消すことができる。Target(Self)のピン。

MyActor.h

UFUNCTION(BlueprintCallable, Category = "Actor Functions", meta=(HideSelfPin="true"))
int32 MultiplicationPure(int32 ValA, int32 ValB) const;

👇BlueprintCallableで作ったのにSelf Pinがない。

(参考)デフォルトではBlueprintCallableにはSelf Pinがある。

BlueprintCallableの方はSelf Pinがあるが、META TAGで消せる。

FUNCTION PARAMETERS

記述の型

const 型名 変数名

設定した変数が変化するとコンパイル時にエラーが出てくれる。
変化させたくない変数に対して設定する。

👇コンパイル時にエラー。

void AMyActor::PrintInt(const int32 value)
{
	value = 3;
	UKismetSystemLibrary::PrintString(this, FString::Printf(TEXT("Print Int %d"), value), true, true, FColor::Red, 10.0f);
}

(Valueに3を代入して、変数の値を変化させてしまっている)

👇これはコンパイル成功。constつけてないから。

void AMyActor::PrintInt(int32 value)
{
value = 3;
UKismetSystemLibrary::PrintString(this, FString::Printf(TEXT("Print Int %d"), value), true, true, FColor::Red, 10.0f);
}

記述の型

型名& 変数名

Outputピンの変数の型と変数名を設定できる。複数記述することで、複数のOutputピンを持たせることも可能。
整数を2乗するノード

MyActor.h

UFUNCTION(BlueprintCallable, Category = "Actor Functions", meta = (HideSelfPin = "true", ToolTip = "Square the Integer."))
void SquareInt(const int32 Value, int32& SquaredValue);

MyActor.cpp

void AMyActor::SquareInt(const int32 Value, int32& SquaredValue)
{
SquaredValue = Value * Value;
}

👇Outputを複数に増やすのも簡単。

記述の型

クラス名* 変数名

*の後ろに&をつけるとOutputピンになる。

入れたものを出すだけの簡単な仕事
MyActor.h

UFUNCTION(BlueprintPure, Category = "Actor Functions")
void ObjectReferencePure(AMyActor* InMyActor, AMyActor*& OutMyActor);

MyActor.cpp

void AMyActor::ObjectReferencePure(AMyActor* InMyActor, AMyActor*& OutMyActor)
{
OutMyActor = InMyActor;
}

BP_MyActorと出力。ここで出力されるのはインスタンスの名前。クラスの名前ではない。

Structureは、頭文字にFをつける。ベクトルは構造体の一種なので、VectorではなくFVectorになる。
これも型名の後ろに&をつけるとOutputピンになる。

MyActor.h

UFUNCTION(BlueprintPure, Category = "Actor Functions")
void InOutLocation(FVector InLocation, FVector& OutLocation);

MyActor.cpp

void AMyActor::InOutLocation(FVector InLocation, FVector& OutLocation)
{
OutLocation = InLocation;
}

GetActorLocationとか作ってみたかったけど、コンパイルエラーになって妥協した。

記述の型

UPARAM(ref) 型名& 変数名

&はついているけどInputピンになる。

MyActor.h

UFUNCTION(BlueprintCallable, Category = "Actor Functions", meta=(HideSelfPin="true"))
void ChangeFloat(UPARAM(ref) float& OldFloat, float NewFloat);

MyActor.cpp

void AMyActor::ChangeFloat(float& OldFloat, float NewFloat)
{
OldFloat = NewFloat;
}

👇スピードの変更ができる。

👇こんなのも作ってみたけど、よく考えたらコレ実行できない。

アウトプットを作る必要あり。

修正

その他

親のクラスを変更できる。便利。

File>Reparent Blueprint

意味要約

Object:U
Actor:A
Structure:F(今回はFVectorで使った)
Enum:E
その他:F

スネークケースと合わせて覚える。

https://wa3.i-3-i.info/word1179.html

意味中括弧(波括弧)
関連
丸括弧 (parentheses)、角括弧 (square bracket)
the open curly brace 開き中括弧
the close curly brace 閉じ中括弧

ヘッダーファイルの一番上にまとめて定義する。
boolではなくuint8を使って、コンストラクタで値を初期化する。

MyActor.h

MyActor.cpp

変数として設定するより、関数の型として設定する方がいいらしい。理由は分からないけど、処理の重さとかかな。

良い例

MyActor.h

UFUNCTION(BlueprintPure, Category = "Actor Functions")
bool InOutLocation(FVector InLocation, FVector& OutLocation);

MyActor.cpp

bool AMyActor::InOutLocation(FVector InLocation, FVector& OutLocation)
{
OutLocation = InLocation;
return true;
}

良くない例

ピンの名前を変えられるってメリットはありそう。

MyActor.h

UFUNCTION(BlueprintPure, Category = "Actor Functions")
void InOutLocation(FVector InLocation, FVector& OutLocation, bool& Outbool);

MyActor.cpp

void AMyActor::InOutLocation(FVector InLocation, FVector& OutLocation, bool& Outbool)
{
OutLocation = InLocation;
Outbool = true;
}

👇参考動画

UE4 – Blueprints to C++ Episode 3 – UFUNCTION

Twitterしてます

ブログの更新をお知らせ

コメント

タイトルとURLをコピーしました