学んだこと、試したこと、気づいたことをまとめています。
はじめに
配列とだいたい同じもの。特徴は下記のとおり。
・順序が保存されない
・値の重複を許さない
・配列より高速
(Getなどを使えない。インデックスがないので。)
👇こちらの動画を参照しました。
UEのC++におけるセット。
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となっていた。要素の値とは関係ない。
セットにはインデックスが無くても、順番の情報は入っているようだ。
記述の型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);
}
分かった気にはなってきた。
記述の型
セット.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(要素 : セット){処理:}
の形のコードとしてとらえている。間違ってても許して。
英語power
記述の型
pow(底, 指数)
例5の2乗
pow(5.0, 2.0)
2の部分を3に変えたら3乗になったりする。
小数点に関するルールは良く分かっていないので適当。
関連
指数:exponent
底:Base
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);
}
👇参考動画
Twitterしてます
ブログの更新をお知らせ
コメント