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);
367 FTransform& OutTransf,
369 const bool ReturnIdentityWithNullptr =
true,
371 const bool Verbose =
false)
377 if (RefActor ==
nullptr)
381 if (ReturnIdentityWithNullptr)
385 OutTransf = FTransform::Identity;
399 UE_LOG(LogTemp, Error, TEXT(
"RefActor is not valid."));
413 OutTransf = RefActor->GetTransform();
454 const AActor* RefActor,
456 const UObject* WorldContextObject,
458 FTransform& OutTransf,
460 const bool Verbose =
false)
464 bool res = GetRefTransformByActor(RefActor, OutTransf, Verbose);
470 res = GetRefTransformByName(RefActorName, WorldContextObject, OutTransf, Verbose);
507 if (RefActor ==
nullptr)
511 OutTransf = FTransform::Identity;
517 UE_LOG(LogTemp, Error, TEXT(
"RefActor is not valid."));
525 OutTransf = RefActor->GetTransform();
560 const UObject* WorldContextObject,
562 FTransform& OutTransf,
564 const bool Verbose =
false)
568 if (RefActorName.IsEmpty())
572 OutTransf = FTransform::Identity;
580 if (WorldContextObject ==
nullptr)
584 OutTransf = FTransform::Identity;
590 UE_LOG(LogTemp, Error, TEXT(
"World is not given. Return Idnetity Transform"));
602 if (refActor ==
nullptr)
606 OutTransf = FTransform::Identity;
612 UE_LOG(LogTemp, Warning, TEXT(
"Reference Actor %s is not valid."), *RefActorName);
622 OutTransf = refActor->GetTransform();
653 const FTransform& WorldTransf,
655 const bool IgnoreScale =
false)
659 FTransform worldTransf = WorldTransf;
661 FTransform refTransfNormalized = RefTransf;
663 refTransfNormalized.NormalizeRotation();
669 worldTransf.SetScale3D(FVector::OneVector);
671 refTransfNormalized.SetScale3D(FVector::OneVector);
677 FTransform relativeTransf = worldTransf.GetRelativeTransform(refTransfNormalized);
679 relativeTransf.NormalizeRotation();
683 return relativeTransf;
709 const FTransform& WorldTransf,
711 const bool IgnoreScale =
false,
713 const bool Verbose =
false)
717 FTransform outTransf;
719 GetRefTransformByActor(RefActor, outTransf, Verbose);
721 return GetRelativeTransform(outTransf, WorldTransf, IgnoreScale);
749 const UObject* WorldContextObject,
751 const FTransform& WorldTransf,
753 const bool IgnoreScale =
false,
755 const bool Verbose =
false)
759 FTransform outTransf;
761 GetRefTransformByName(RefActorName, WorldContextObject, outTransf, Verbose);
763 return GetRelativeTransform(outTransf, WorldTransf, IgnoreScale);
794 const FTransform& WorldTransf,
796 const bool IgnoreScale =
false,
798 const bool Verbose =
false)
802 return GetRelativeTransform(RefActor, WorldTransf, IgnoreScale, Verbose);
835 const UObject* WorldContextObject,
837 const FTransform& WorldTransf,
839 const bool IgnoreScale =
false,
841 const bool Verbose =
false)
845 return GetRelativeTransform(RefActorName, WorldContextObject, WorldTransf, IgnoreScale, Verbose);
875 const FTransform& InTransf,
877 FTransform& OutTransf,
879 const bool IgnoreScale =
false,
881 const bool ReturnIdentityWithNullptr =
true,
883 const bool Verbose =
false)
887 FTransform refTransf;
889 bool result = GetRefTransform(RefActor, refTransf, ReturnIdentityWithNullptr, Verbose);
895 OutTransf = GetRelativeTransform(refTransf, InTransf, IgnoreScale);
927 const AActor* RefActor,
929 const FTransform& InTransf,
931 const UObject* WorldContextObject,
933 FTransform& OutTransf,
935 const bool IgnoreScale =
false,
937 const bool Verbose =
false)
941 FTransform refTransf;
943 bool result = GetRefTransform(RefActorName, RefActor, WorldContextObject, refTransf, Verbose);
949 OutTransf = GetRelativeTransform(refTransf, InTransf, IgnoreScale);
982 const FTransform& RelativeTransf,
984 const bool IgnoreScale =
false)
988 FTransform worldTransf;
990 FTransform refTransf = RefTransf;
992 FTransform relativeTransf = RelativeTransf;
998 refTransf.SetScale3D(FVector::OneVector);
1000 relativeTransf.SetScale3D(FVector::OneVector);
1006 FTransform::Multiply(&worldTransf, &relativeTransf, &refTransf);
1010 worldTransf.NormalizeRotation();
1040 const FTransform& RelativeTransf,
1042 const bool IgnoreScale =
false,
1044 const bool Verbose =
false)
1048 FTransform outTransf;
1050 GetRefTransformByActor(RefActor, outTransf, Verbose);
1052 return GetWorldTransform(outTransf, RelativeTransf, IgnoreScale);
1082 const UObject* WorldContextObject,
1084 const FTransform& RelativeTransf,
1086 const bool IgnoreScale =
false,
1088 const bool Verbose =
false)
1092 FTransform outTransf;
1094 GetRefTransformByName(RefActorName, WorldContextObject, outTransf, Verbose);
1096 return GetWorldTransform(outTransf, RelativeTransf, IgnoreScale);
1127 const FTransform& RelativeTransf,
1129 const bool IgnoreScale =
false,
1131 const bool Verbose =
false)
1135 return GetWorldTransform(RefActor, RelativeTransf, IgnoreScale, Verbose);
1168 const UObject* WorldContextObject,
1170 const FTransform& RelativeTransf,
1172 const bool IgnoreScale =
false,
1174 const bool Verbose =
false)
1178 return GetWorldTransform(RefActorName, WorldContextObject, RelativeTransf, IgnoreScale, Verbose);
1212 const FTransform& InTransf,
1214 FTransform& OutTransf,
1216 const bool ReturnIdentityWithNullptr =
true,
1218 const bool IgnoreScale =
false,
1220 const bool Verbose =
false)
1224 FTransform refTransf;
1226 bool result = GetRefTransform(RefActor, refTransf, ReturnIdentityWithNullptr, Verbose);
1232 OutTransf = GetWorldTransform(refTransf, InTransf, IgnoreScale);
1266 const AActor* RefActor,
1268 const FTransform& InTransf,
1270 const UObject* WorldContextObject,
1272 FTransform& OutTransf,
1274 const bool IgnoreScale =
false)
1278 FTransform refTransf;
1280 bool result = GetRefTransform(RefActorName, RefActor, WorldContextObject, refTransf);
1286 OutTransf = GetWorldTransform(refTransf, InTransf, IgnoreScale);
1312 return FString::Printf(TEXT(
"UE%s_%s"), *InAffix, *FGuid::NewGuid().ToString());
1336 return InPrefix.IsEmpty() ? InFrameId : FString::Printf(TEXT(
"%s/%s"), *InPrefix, InFrameId);
1358 FORCEINLINE
static bool GetJsonField(
const TSharedPtr<FJsonObject>& InJsonObj,
const FString& InFieldName, FString& OutValue)
1362 return InJsonObj.Get()->TryGetStringField(InFieldName, OutValue);
1384 FORCEINLINE
static bool GetJsonField(
const TSharedPtr<FJsonObject>& InJsonObj,
1386 const FString& InFieldName,
1390 float InMultiplier = 1.f)
1396 bool bFieldFound = InJsonObj.Get()->TryGetNumberField(InFieldName, resultValue);
1406 OutValue =
static_cast<float>(resultValue) * InMultiplier;
1430 FORCEINLINE
static bool GetJsonField(
const TSharedPtr<FJsonObject>& InJsonObj,
1432 const FString& InFieldName,
1436 double InMultiplier = 1.)
1440 bool bFieldFound = InJsonObj.Get()->TryGetNumberField(InFieldName, OutValue);
1450 OutValue *= InMultiplier;
1472 FORCEINLINE
static bool GetJsonField(
const TSharedPtr<FJsonObject>& InJsonObj,
const FString& InFieldName,
int& OutValue)
1476 return InJsonObj.Get()->TryGetNumberField(InFieldName, OutValue);
1496 FORCEINLINE
static bool GetJsonField(
const TSharedPtr<FJsonObject>& InJsonObj,
const FString& InFieldName,
bool& OutValue)
1500 return InJsonObj.Get()->TryGetBoolField(InFieldName, OutValue);
1522 FORCEINLINE
static bool GetJsonField(
const TSharedPtr<FJsonObject>& InJsonObj,
const FString& InFieldName, FVector& OutValue)
1528 auto const tempJsonObj = InJsonObj->GetObjectField(InFieldName);
1530 res &= tempJsonObj.Get()->TryGetNumberField(TEXT(
"x"), OutValue.X);
1532 res &= tempJsonObj.Get()->TryGetNumberField(TEXT(
"y"), OutValue.Y);
1534 res &= tempJsonObj.Get()->TryGetNumberField(TEXT(
"z"), OutValue.Z);
1560 FORCEINLINE
static bool GetJsonField(
const TSharedPtr<FJsonObject>& InJsonObj,
const FString& InFieldName, FRotator& OutValue)
1566 auto const tempJsonObj = InJsonObj->GetObjectField(InFieldName);
1568 res &= tempJsonObj.Get()->TryGetNumberField(TEXT(
"roll"), OutValue.Roll);
1570 res &= tempJsonObj.Get()->TryGetNumberField(TEXT(
"pitch"), OutValue.Pitch);
1572 res &= tempJsonObj.Get()->TryGetNumberField(TEXT(
"yaw"), OutValue.Yaw);
1598 FORCEINLINE
static bool GetJsonField(
const TSharedPtr<FJsonObject>& InJsonObj,
const FString& InFieldName, FQuat& OutValue)
1604 auto const tempJsonObj = InJsonObj->GetObjectField(InFieldName);
1606 res &= tempJsonObj.Get()->TryGetNumberField(TEXT(
"x"), OutValue.X);
1608 res &= tempJsonObj.Get()->TryGetNumberField(TEXT(
"y"), OutValue.Y);
1610 res &= tempJsonObj.Get()->TryGetNumberField(TEXT(
"z"), OutValue.Z);
1612 res &= tempJsonObj.Get()->TryGetNumberField(TEXT(
"w"), OutValue.W);
1638 FORCEINLINE
static bool GetJsonField(
const TSharedPtr<FJsonObject>& InJsonObj,
const FString& InFieldName, FTransform& OutValue)
1644 FVector vectorParam = FVector::ZeroVector;
1646 FRotator rotatorParam = FRotator::ZeroRotator;
1648 auto const tempJsonObj = InJsonObj->GetObjectField(InFieldName);
1650 res &= GetJsonField(tempJsonObj, TEXT(
"position"), vectorParam);
1652 res &= GetJsonField(tempJsonObj, TEXT(
"orientation"), rotatorParam);
1654 OutValue = FTransform(rotatorParam, vectorParam, FVector::OneVector);
1682 template<
typename T>
1684 static bool GetJsonField(
const FString& InJsonString,
const FString& InFieldName, T& OutValue)
1688 TSharedRef<TJsonReader<TCHAR>> jsonReader = TJsonReaderFactory<TCHAR>::Create(InJsonString);
1690 TSharedPtr<FJsonObject> jsonObj = MakeShareable(
new FJsonObject());
1692 if (!FJsonSerializer::Deserialize(jsonReader, jsonObj) && jsonObj.IsValid())
1696 UE_LOG(LogTemp, Error, TEXT(
"Failed to deserialize json to object"));
1702 return GetJsonField(jsonObj, InFieldName, OutValue);
1729 static bool GetJsonFieldVector(
const FString& InJsonString,
const FString& InFieldName, FVector& OutValue)
1733 return GetJsonField<FVector>(InJsonString, InFieldName, OutValue);
1764 return GetJsonField<FRotator>(InJsonString, InFieldName, OutValue);
1791 static bool GetJsonFieldQuat(
const FString& InJsonString,
const FString& InFieldName, FQuat& OutValue)
1795 return GetJsonField<FQuat>(InJsonString, InFieldName, OutValue);
1826 return GetJsonField<FTransform>(InJsonString, InFieldName, OutValue);
1852 template<
typename T>
1856 const FString& InFieldName,
1858 const T& InDefaultValue,
1864 if (GetJsonField(InJsonObj, InFieldName, OutValue))
1872 OutValue = InDefaultValue;
1903 UPrimitiveComponent* PrimComp = NULL;
1913 if (ComponentName == NAME_None)
1917 PrimComp = Cast<UPrimitiveComponent>(Actor->GetRootComponent());
1927 for (UActorComponent* Comp : Actor->GetComponents())
1931 if (Comp->GetFName() == ComponentName)
1935 if (UChildActorComponent* ChildActorComp = Cast<UChildActorComponent>(Comp))
1939 if (AActor* ChildActor = ChildActorComp->GetChildActor())
1943 PrimComp = Cast<UPrimitiveComponent>(ChildActor->GetRootComponent());
1953 PrimComp = Cast<UPrimitiveComponent>(Comp);
1998 EConstraintFrame::Type Frame)
2002 if (InConstraint !=
nullptr)
2006 UPrimitiveComponent* PrimComp = NULL;
2010 FName ComponentName = NAME_None;
2012 AActor* Actor = NULL;
2018 if (Frame == EConstraintFrame::Frame1)
2024 if (InConstraint->OverrideComponent1.IsValid())
2028 return InConstraint->OverrideComponent1.Get();
2034 ComponentName = InConstraint->ComponentName1.ComponentName;
2036 Actor = InConstraint->ConstraintActor1;
2048 if (InConstraint->OverrideComponent2.IsValid())
2052 return InConstraint->OverrideComponent2.Get();
2058 ComponentName = InConstraint->ComponentName2.ComponentName;
2060 Actor = InConstraint->ConstraintActor2;
2066 return GetComponentOfActorFromName(Actor, ComponentName);
2074 UE_LOG(LogTemp, Error, TEXT(
"[GetPhysicsConstraintComponent]Physics Constraint is not valid."));
2107 const FTransform InitialJointToChildLink,
2109 UPrimitiveComponent* InChildLink =
nullptr)
2113 FTransform outTF = FTransform::Identity;
2115 if (InConstraint !=
nullptr)
2119 UPrimitiveComponent* ChildLink = InChildLink;
2121 if (ChildLink ==
nullptr)
2125 ChildLink = GetPhysicsConstraintComponent(InConstraint, EConstraintFrame::Frame2);
2131 if (ChildLink !=
nullptr)
2137 ChildLink->GetComponentTransform());
2141 FVector position = relativeTrans.GetLocation() - InitialJointToChildLink.GetLocation();
2143 FRotator orientation = (relativeTrans.GetRotation() * InitialJointToChildLink.GetRotation().Inverse()).Rotator();
2147 outTF.SetLocation(position);
2149 outTF.SetRotation(orientation.Quaternion());
2157 outTF = FTransform::Identity;
2167 UE_LOG(LogTemp, Error, TEXT(
"[GetPhysicsConstraintTransform]Physics Constraint is not valid."));
2169 outTF = FTransform::Identity;
2201 const FTransform InitialJointToChildLink,
2203 FVector& OutPosition,
2205 FRotator& OutOrientation,
2207 UPrimitiveComponent* InChildLink =
nullptr)
2211 FTransform tf = GetPhysicsConstraintTransform(InConstraint, InitialJointToChildLink, InChildLink);
2213 OutPosition = tf.GetLocation();
2215 OutOrientation = tf.GetRotation().Rotator();
2226 static FString
PascalToSnake(
const FString& InPascalString,
const bool InCheckNum =
false)
2230 FString output = TEXT(
"");
2232 for (int32 i = 0; i < InPascalString.Len(); i++)
2236 FString currStr = InPascalString.Mid(i, 1);
2238 FString newStr = currStr;
2240 if (i > 0 && (isupper(*TCHAR_TO_ANSI(*currStr)) || (InCheckNum && currStr.IsNumeric())))
2244 newStr = TEXT(
"_") + newStr.ToLower();
2252 newStr = newStr.ToLower();
2256 output.Append(newStr);
2273 const TSubclassOf<UActorComponent> InComponentClass,
2275 bool bIncludeAllDescendants =
false)
2279 TArray<USceneComponent*> children;
2281 InTarget->GetChildrenComponents(bIncludeAllDescendants, children);
2283 for (
const auto& child : children)
2287 if (child->IsA(InComponentClass))