19 #include "Engine/World.h"
21 #include "EngineUtils.h"
25 #include "Kismet/KismetSystemLibrary.h"
27 #include "PhysicsEngine/PhysicsConstraintComponent.h"
29 #include "TimerManager.h"
37 #include "RRGeneralUtils.generated.h"
43 #define EMPTY_STR (TEXT(""))
60 class RAPYUTASIMULATIONPLUGINS_API
URRGeneralUtils :
public UBlueprintFunctionLibrary
88 static T*
FindActorByName(UWorld* InWorld,
const FString& InName,
const ESearchCase::Type InCaseType = ESearchCase::IgnoreCase)
92 for (TActorIterator<T> actorItr(InWorld); actorItr; ++actorItr)
96 if (actorItr->GetName().Equals(InName, InCaseType))
110 for (TActorIterator<T> actorItr(InWorld); actorItr; ++actorItr)
114 if (UKismetSystemLibrary::GetDisplayName(*actorItr).Equals(InName, InCaseType))
126 UE_LOG(LogTemp, Log, TEXT(
"Actor named [%s] is unavailable."), *InName);
157 const FString& InName,
159 const ESearchCase::Type InCaseType = ESearchCase::IgnoreCase)
163 UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
165 return FindActorByName<AActor>(World, InName, InCaseType);
193 const FString& InSubname,
195 const ESearchCase::Type InCaseType = ESearchCase::IgnoreCase)
199 for (TActorIterator<T> actorItr(InWorld); actorItr; ++actorItr)
203 if (actorItr->GetName().Contains(InSubname, InCaseType))
217 for (TActorIterator<T> actorItr(InWorld); actorItr; ++actorItr)
221 if (UKismetSystemLibrary::GetDisplayName(*actorItr).Contains(InSubname, InCaseType))
233 UE_LOG(LogTemp, Log, TEXT(
"Actor name containing [%s] is unavailable."), *InSubname);
264 const FString& InSubname,
266 const ESearchCase::Type InCaseType = ESearchCase::IgnoreCase)
270 UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
272 return FindActorBySubname<AActor>(World, InSubname, InCaseType);
282 const FString& InSubname,
284 const ESearchCase::Type InCaseType = ESearchCase::IgnoreCase)
290 for (TActorIterator<T> actorItr(InWorld); actorItr; ++actorItr)
294 if (actorItr->GetName().Contains(InSubname, InCaseType))
298 actors.Add(*actorItr);
306 else if (UKismetSystemLibrary::GetDisplayName(*actorItr).Contains(InSubname, InCaseType))
310 actors.Add(*actorItr);
333 const FString& InSubname,
335 const ESearchCase::Type InCaseType = ESearchCase::IgnoreCase)
339 UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
341 return FindActorListBySubname<AActor>(World, InSubname, InCaseType);
365 static bool GetRefTransform(
const FString& RefActorName,
const AActor* RefActor, FTransform& OutTransf)
369 if (RefActorName.IsEmpty())
373 OutTransf = FTransform::Identity;
381 if (RefActor ==
nullptr)
389 OutTransf = RefActor->GetTransform();
428 const AActor* RefActor,
430 const UObject* WorldContextObject,
432 FTransform& OutTransf,
434 const bool Verbose =
false)
438 bool res = GetRefTransformByActor(RefActor, OutTransf, Verbose);
444 res = GetRefTransformByName(RefActorName, WorldContextObject, OutTransf, Verbose);
481 if (RefActor ==
nullptr)
485 OutTransf = FTransform::Identity;
491 UE_LOG(LogTemp, Error, TEXT(
"RefActor is not valid."));
499 OutTransf = RefActor->GetTransform();
534 const UObject* WorldContextObject,
536 FTransform& OutTransf,
538 const bool Verbose =
false)
542 if (RefActorName.IsEmpty())
546 OutTransf = FTransform::Identity;
554 if (WorldContextObject ==
nullptr)
558 OutTransf = FTransform::Identity;
564 UE_LOG(LogTemp, Error, TEXT(
"World is not given. Return Idnetity Transform"));
576 if (refActor ==
nullptr)
580 OutTransf = FTransform::Identity;
586 UE_LOG(LogTemp, Warning, TEXT(
"Reference Actor %s is not valid."), *RefActorName);
596 OutTransf = refActor->GetTransform();
627 FTransform refTransfNormalized = RefTransf;
629 refTransfNormalized.NormalizeRotation();
633 FTransform relativeTransf = WorldTransf.GetRelativeTransform(refTransfNormalized);
635 relativeTransf.NormalizeRotation();
639 return relativeTransf;
659 static FTransform
GetRelativeTransform(
const AActor* RefActor,
const FTransform& WorldTransf,
const bool Verbose =
false)
663 FTransform outTransf;
665 GetRefTransformByActor(RefActor, outTransf, Verbose);
667 return GetRelativeTransform(outTransf, WorldTransf);
691 const UObject* WorldContextObject,
693 const FTransform& WorldTransf,
695 const bool Verbose =
false)
699 FTransform outTransf;
701 GetRefTransformByName(RefActorName, WorldContextObject, outTransf, Verbose);
703 return GetRelativeTransform(outTransf, WorldTransf);
730 const FTransform& WorldTransf,
732 const bool Verbose =
false)
736 return GetRelativeTransform(RefActor, WorldTransf, Verbose);
763 const UObject* WorldContextObject,
765 const FTransform& WorldTransf,
767 const bool Verbose =
false)
771 return GetRelativeTransform(RefActorName, WorldContextObject, WorldTransf, Verbose);
799 const AActor* RefActor,
801 const FTransform& InTransf,
803 FTransform& OutTransf)
807 FTransform refTransf;
809 bool result = GetRefTransform(RefActorName, RefActor, refTransf);
847 const AActor* RefActor,
849 const FTransform& InTransf,
851 const UObject* WorldContextObject,
853 FTransform& OutTransf)
857 FTransform refTransf;
859 bool result = GetRefTransform(RefActorName, RefActor, WorldContextObject, refTransf);
894 static FTransform
GetWorldTransform(
const FTransform& RefTransf,
const FTransform& RelativeTransf)
898 FTransform worldTransf;
902 FTransform::Multiply(&worldTransf, &RelativeTransf, &RefTransf);
906 worldTransf.NormalizeRotation();
930 static FTransform
GetWorldTransform(
const AActor* RefActor,
const FTransform& RelativeTransf,
const bool Verbose =
false)
934 FTransform outTransf;
936 GetRefTransformByActor(RefActor, outTransf, Verbose);
938 return GetWorldTransform(outTransf, RelativeTransf);
966 const UObject* WorldContextObject,
968 const FTransform& RelativeTransf,
970 const bool Verbose =
false)
974 FTransform outTransf;
976 GetRefTransformByName(RefActorName, WorldContextObject, outTransf, Verbose);
978 return GetWorldTransform(outTransf, RelativeTransf);
1005 const FTransform& RelativeTransf,
1007 const bool Verbose =
false)
1011 return GetWorldTransform(RefActor, RelativeTransf, Verbose);
1038 const UObject* WorldContextObject,
1040 const FTransform& RelativeTransf,
1042 const bool Verbose =
false)
1046 return GetWorldTransform(RefActorName, WorldContextObject, RelativeTransf, Verbose);
1076 const AActor* RefActor,
1078 const FTransform& InTransf,
1080 FTransform& OutTransf)
1084 FTransform refTransf;
1086 bool result = GetRefTransform(RefActorName, RefActor, refTransf);
1126 const AActor* RefActor,
1128 const FTransform& InTransf,
1130 const UObject* WorldContextObject,
1132 FTransform& OutTransf)
1136 FTransform refTransf;
1138 bool result = GetRefTransform(RefActorName, RefActor, WorldContextObject, refTransf);
1170 return FString::Printf(TEXT(
"UE%s_%s"), *InAffix, *FGuid::NewGuid().ToString());
1194 return InPrefix.IsEmpty() ? InFrameId : FString::Printf(TEXT(
"%s/%s"), *InPrefix, InFrameId);
1216 FORCEINLINE
static bool GetJsonField(
const TSharedPtr<FJsonObject>& InJsonObj,
const FString& InFieldName, FString& OutValue)
1220 return InJsonObj.Get()->TryGetStringField(InFieldName, OutValue);
1242 FORCEINLINE
static bool GetJsonField(
const TSharedPtr<FJsonObject>& InJsonObj,
1244 const FString& InFieldName,
1248 float InMultiplier = 1.f)
1254 bool bFieldFound = InJsonObj.Get()->TryGetNumberField(InFieldName, resultValue);
1264 OutValue =
static_cast<float>(resultValue) * InMultiplier;
1288 FORCEINLINE
static bool GetJsonField(
const TSharedPtr<FJsonObject>& InJsonObj,
1290 const FString& InFieldName,
1294 double InMultiplier = 1.)
1298 bool bFieldFound = InJsonObj.Get()->TryGetNumberField(InFieldName, OutValue);
1308 OutValue *= InMultiplier;
1330 FORCEINLINE
static bool GetJsonField(
const TSharedPtr<FJsonObject>& InJsonObj,
const FString& InFieldName,
int& OutValue)
1334 return InJsonObj.Get()->TryGetNumberField(InFieldName, OutValue);
1354 FORCEINLINE
static bool GetJsonField(
const TSharedPtr<FJsonObject>& InJsonObj,
const FString& InFieldName,
bool& OutValue)
1358 return InJsonObj.Get()->TryGetBoolField(InFieldName, OutValue);
1380 FORCEINLINE
static bool GetJsonField(
const TSharedPtr<FJsonObject>& InJsonObj,
const FString& InFieldName, FVector& OutValue)
1386 auto const tempJsonObj = InJsonObj->GetObjectField(InFieldName);
1388 res &= tempJsonObj.Get()->TryGetNumberField(TEXT(
"x"), OutValue.X);
1390 res &= tempJsonObj.Get()->TryGetNumberField(TEXT(
"y"), OutValue.Y);
1392 res &= tempJsonObj.Get()->TryGetNumberField(TEXT(
"z"), OutValue.Z);
1418 FORCEINLINE
static bool GetJsonField(
const TSharedPtr<FJsonObject>& InJsonObj,
const FString& InFieldName, FRotator& OutValue)
1424 auto const tempJsonObj = InJsonObj->GetObjectField(InFieldName);
1426 res &= tempJsonObj.Get()->TryGetNumberField(TEXT(
"roll"), OutValue.Roll);
1428 res &= tempJsonObj.Get()->TryGetNumberField(TEXT(
"pitch"), OutValue.Pitch);
1430 res &= tempJsonObj.Get()->TryGetNumberField(TEXT(
"yaw"), OutValue.Yaw);
1456 FORCEINLINE
static bool GetJsonField(
const TSharedPtr<FJsonObject>& InJsonObj,
const FString& InFieldName, FQuat& OutValue)
1462 auto const tempJsonObj = InJsonObj->GetObjectField(InFieldName);
1464 res &= tempJsonObj.Get()->TryGetNumberField(TEXT(
"x"), OutValue.X);
1466 res &= tempJsonObj.Get()->TryGetNumberField(TEXT(
"y"), OutValue.Y);
1468 res &= tempJsonObj.Get()->TryGetNumberField(TEXT(
"z"), OutValue.Z);
1470 res &= tempJsonObj.Get()->TryGetNumberField(TEXT(
"w"), OutValue.W);
1496 FORCEINLINE
static bool GetJsonField(
const TSharedPtr<FJsonObject>& InJsonObj,
const FString& InFieldName, FTransform& OutValue)
1502 FVector vectorParam = FVector::ZeroVector;
1504 FRotator rotatorParam = FRotator::ZeroRotator;
1506 auto const tempJsonObj = InJsonObj->GetObjectField(InFieldName);
1508 res &= GetJsonField(tempJsonObj, TEXT(
"position"), vectorParam);
1510 res &= GetJsonField(tempJsonObj, TEXT(
"orientation"), rotatorParam);
1512 OutValue = FTransform(rotatorParam, vectorParam, FVector::OneVector);
1542 template<
typename T>
1546 const FString& InFieldName,
1548 const T& InDefaultValue,
1554 if (GetJsonField(InJsonObj, InFieldName, OutValue))
1562 OutValue = InDefaultValue;
1593 UPrimitiveComponent* PrimComp = NULL;
1603 if (ComponentName == NAME_None)
1607 PrimComp = Cast<UPrimitiveComponent>(Actor->GetRootComponent());
1617 for (UActorComponent* Comp : Actor->GetComponents())
1621 if (Comp->GetFName() == ComponentName)
1625 if (UChildActorComponent* ChildActorComp = Cast<UChildActorComponent>(Comp))
1629 if (AActor* ChildActor = ChildActorComp->GetChildActor())
1633 PrimComp = Cast<UPrimitiveComponent>(ChildActor->GetRootComponent());
1643 PrimComp = Cast<UPrimitiveComponent>(Comp);
1688 EConstraintFrame::Type Frame)
1692 if (InConstraint !=
nullptr)
1696 UPrimitiveComponent* PrimComp = NULL;
1700 FName ComponentName = NAME_None;
1702 AActor* Actor = NULL;
1708 if (Frame == EConstraintFrame::Frame1)
1714 if (InConstraint->OverrideComponent1.IsValid())
1718 return InConstraint->OverrideComponent1.Get();
1724 ComponentName = InConstraint->ComponentName1.ComponentName;
1726 Actor = InConstraint->ConstraintActor1;
1738 if (InConstraint->OverrideComponent2.IsValid())
1742 return InConstraint->OverrideComponent2.Get();
1748 ComponentName = InConstraint->ComponentName2.ComponentName;
1750 Actor = InConstraint->ConstraintActor2;
1756 return GetComponentOfActorFromName(Actor, ComponentName);
1764 UE_LOG(LogTemp, Error, TEXT(
"[GetPhysicsConstraintComponent]Physics Constraint is not valid."));
1797 const FTransform InitialJointToChildLink,
1799 UPrimitiveComponent* InChildLink =
nullptr)
1803 FTransform outTF = FTransform::Identity;
1805 if (InConstraint !=
nullptr)
1809 UPrimitiveComponent* ChildLink = InChildLink;
1811 if (ChildLink ==
nullptr)
1815 ChildLink = GetPhysicsConstraintComponent(InConstraint, EConstraintFrame::Frame2);
1821 if (ChildLink !=
nullptr)
1827 ChildLink->GetComponentTransform());
1831 FVector position = relativeTrans.GetLocation() - InitialJointToChildLink.GetLocation();
1833 FRotator orientation = (relativeTrans.GetRotation() * InitialJointToChildLink.GetRotation().Inverse()).Rotator();
1837 outTF.SetLocation(position);
1839 outTF.SetRotation(orientation.Quaternion());
1847 outTF = FTransform::Identity;
1857 UE_LOG(LogTemp, Error, TEXT(
"[GetPhysicsConstraintTransform]Physics Constraint is not valid."));
1859 outTF = FTransform::Identity;
1891 const FTransform InitialJointToChildLink,
1893 FVector& OutPosition,
1895 FRotator& OutOrientation,
1897 UPrimitiveComponent* InChildLink =
nullptr)
1901 FTransform tf = GetPhysicsConstraintTransform(InConstraint, InitialJointToChildLink, InChildLink);
1903 OutPosition = tf.GetLocation();
1905 OutOrientation = tf.GetRotation().Rotator();
1916 static FString
PascalToSnake(
const FString& InPascalString,
const bool InCheckNum =
false)
1920 FString output = TEXT(
"");
1922 for (int32 i = 0; i < InPascalString.Len(); i++)
1926 FString currStr = InPascalString.Mid(i, 1);
1928 FString newStr = currStr;
1930 if (i > 0 && (isupper(*TCHAR_TO_ANSI(*currStr)) || (InCheckNum && currStr.IsNumeric())))
1934 newStr = TEXT(
"_") + newStr.ToLower();
1942 newStr = newStr.ToLower();
1946 output.Append(newStr);
1963 const TSubclassOf<UActorComponent> InComponentClass,
1965 bool bIncludeAllDescendants =
false)
1969 TArray<USceneComponent*> children;
1971 InTarget->GetChildrenComponents(bIncludeAllDescendants, children);
1973 for (
const auto& child : children)
1977 if (child->IsA(InComponentClass))