【UE5】セットの基本【C++】

学んだこと、試したこと、気づいたことをまとめています。

はじめに

配列とだいたい同じもの。特徴は下記のとおり。
・順序が保存されない
・値の重複を許さない
・配列より高速
(Getなどを使えない。インデックスがないので。)
👇こちらの動画を参照しました。

【UE4/UE5ゲーム制作講座】超基礎編・これを見れば配列・マップ・セットがわかる!

UEのC++におけるセット。

TSets は、順序が重要ではないユニークなエレメントを格納する高速のコンテナクラスです。

公式ドキュメント

TSet
TSets は、順序が重要ではないユニークなエレメントを格納する高速のコンテナ クラスです。

MyActor.h

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyActor")
	TSet<FVector> VecSet;

ここではベクトルをつかう。

基本操作

記述の型セットを書き換える

セット.Add(要素);

MyActor.h

UFUNCTION(BlueprintCallable, Category = "Actor Functions", meta = (HideSelfPin = "true"))
	void VecSetAdd(UPARAM(ref) TSet<FVector>& InVecSet, FVector AddVec);

MyActor.cpp

void AMyActor::VecSetAdd(TSet<FVector>& InVecSet, FVector AddVec)
{
	InVecSet.Add(AddVec);
}

記述の型セットを書き換える

セット.Append(セット);

MyActor.h

UFUNCTION(BlueprintCallable, Category = "Actor Functions", meta = (HideSelfPin = "true"))
	void VecSetAppend(UPARAM(ref) TSet<FVector>& InVecSet, TSet<FVector> AppendVecSet);

MyActor.cpp

void AMyActor::VecSetAppend(TSet<FVector>& InVecSet, TSet<FVector> AppendVecSet)
{
	InVecSet.Append(AppendVecSet);
}

記述の型整数値を返す

セット.Num()

MyActor.h

UFUNCTION(BlueprintPure, Category = "Actor Functions", meta = (HideSelfPin = "true"))
	int32 VecSetLength(UPARAM(ref) TSet<FVector>& InVecSet);

MyActor.cpp

int32 AMyActor::VecSetLength(TSet<FVector>& InVecSet)
{
	return InVecSet.Num();
}

使い方

セットを配列に変える。

記述の型配列を返す

セット.Array()

MyActor.h

UFUNCTION(BlueprintPure, Category = "Actor Functions", meta = (HideSelfPin = "true"))
TArray<FVector> VecSetToArray(UPARAM(ref) TSet<FVector>& InVecSet);

MyActor.cpp

TArray<FVector> AMyActor::VecSetToArray(TSet<FVector>& InVecSet)
{
	return InVecSet.Array();
}

配列に変更したときのインデックスの割り振り方が疑問だったので調べてみた。
下記の画像だと、上から順に0,1,2となっていた。要素の値とは関係ない。
セットにはインデックスが無くても、順番の情報は入っているようだ。

この場合、Getノードは100を出力する。

記述の型bool値を返す

セット.Contains(要素)

MyActor.h

UFUNCTION(BlueprintPure, Category = "Actor Functions", meta = (HideSelfPin = "true"))
	bool VecSetContains(UPARAM(ref) TSet<FVector>& InVecSet, FVector CheckVec);

MyActor.cpp

bool AMyActor::VecSetContains(TSet<FVector>& InVecSet, FVector CheckVec)
{
	return InVecSet.Contains(CheckVec);
}

分かった気にはなってきた。

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

記述の型

セット.Find(要素)

セットにはインデックスがないので、Xの値を返す処理にしている。正直ポインタについては理解できていないので、実際に使ってみる中で理解しようと目論んでいる。
ちなみに、存在しない要素を探すとエラーがでる。

MyActor.h

UFUNCTION(BlueprintPure, Category = "Actor Functions", meta = (HideSelfPin = "true"))
int32 VecSetFind(UPARAM(ref) TSet<FVector>& InVecSet, FVector CheckVec);

MyActor.cpp

int32 AMyActor::VecSetFind(TSet<FVector>& InVecSet, FVector CheckVec)
{
	const FVector* VecPtr = InVecSet.Find(CheckVec);
	return VecPtr->X;
}

関連VecSetFindRef(失敗)

参照渡しは上手くいかない。でも、とりあえずXの値を返すことはできている。ここら辺からポインタの意味や使い方を推測していきたい。

MyActor.h

UFUNCTION(BlueprintPure, Category = "Actor Functions", meta = (HideSelfPin = "true"))
	int32 VecSetFindRef(UPARAM(ref) TSet<FVector>& InVecSet, FVector CheckVec);

MyActor.cpp

int32 AMyActor::VecSetFindRef(TSet<FVector>& InVecSet, FVector CheckVec)
{
	const FVector* VecPtr = InVecSet.Find(CheckVec);
	const FVector& VecRef = *VecPtr;
	return VecRef.X;
}

記述の型セットを書き換える

セット.Remove(要素);

MyActor.h

UFUNCTION(BlueprintCallable, Category = "Actor Functions", meta = (HideSelfPin = "true"))
	bool VeczSetRemove(UPARAM(ref) TSet<FVector>& InVecSet, FVector RemoveVec);

MyActor.cpp

bool AMyActor::VeczSetRemove(TSet<FVector>& InVecSet, FVector RemoveVec)
{
	if (InVecSet.Contains(RemoveVec))
	{
		InVecSet.Remove(RemoveVec);
		return true;
	}
	else
	{
		return false;
	}
}

記述の型セットを書き換える(空にする)

セット.Empty();

MyActor.h

UFUNCTION(BlueprintCallable, Category = "Actor Functions", meta = (HideSelfPin = "true"))
	void VecSetClear(UPARAM(ref) TSet<FVector>& InVecSet);

MyActor.cpp

void AMyActor::VecSetClear(TSet<FVector>& InVecSet)
{
	InVecSet.Empty();
}

イテレーション

インデックスがないので、セットではfor文は使えない。事前に配列に変換する必要がある。
C++では配列に戻さなくてもfor eachが使えるが、BPではセット用のfor each が用意されていない。
注意
ここでは、for文とは、

for(int32 i=0; i<要素数; i++){処理;}

の形のコードで、for eachとは、

for(要素 : セット){処理:}

の形のコードとしてとらえている。間違ってても許して。

セットをFor Eachに繋げると、自動的にToArrayで配列に変換される。

英語power
記述の型

pow(底, 指数)

5の2乗

pow(5.0, 2.0)

2の部分を3に変えたら3乗になったりする。
小数点に関するルールは良く分かっていないので適当。

関連

指数:exponent

底:Base

Math 9: What is a Power?

sqrt = square root

記述の型

sqrt(数)

5の正の平方根

sqrt(5.0)

Magnitude of a vector
いろいろな表現があるかも。Lengthでも良いのかもしれないが、要素数ともかぶるのでLengthは使わない。

セットの中から、一番ベクトルの大きさが大きいものを探す。

MyActor.h

UFUNCTION(BlueprintCallable, Category = "Actor Functions", meta = (HideSelfPin = "true"))
	float VecSetMaxMagnitude(UPARAM(ref) TSet<FVector>& InVecSet);

MyActor.cpp

float AMyActor::VecSetMaxMagnitude(TSet<FVector>& InVecSet)
{
	float MaxLength = 0.0f;
	for (FVector Vec : InVecSet)
	{
		float VecLength = pow(Vec.X, 2.0) + pow(Vec.Y, 2.0) + pow(Vec.Z, 2.0);
			if (MaxLength < VecLength)
			{
				MaxLength = VecLength;
			}
	}
	return sqrt(MaxLength);
}

その他

切り捨て。Floorとの違いは分からない。

KISMET_MATH_FORCEINLINE
int32 UKismetMathLibrary::FFloor(double A)
{
	return FMath::FloorToInt(A);
}	

KISMET_MATH_FORCEINLINE
int32 UKismetMathLibrary::FTrunc(double A)
{
	return FMath::TruncToInt(A);
}

👇参考動画

UE4 – Blueprints to C++ Episode 0 – Introduction

Twitterしてます

ブログの更新をお知らせ

コメント

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