#include "GlobalUtilsLibrary.h" #include "Algo/Transform.h" #include "Misc/Paths.h" #include "HAL/PlatformProcess.h" #include "Kismet/KismetMathLibrary.h" #include "Components/SkeletalMeshComponent.h" #include "ProjectT/ProjectT.h" #include "ProjectT/System/Core/Managers/DataDam.h" #include "ProjectT/System/Core/Interfaces/GlobalObjectProvider.h" #include "ProjectT/System/Core/CoreGameInstance.h" #include "ProjectT/Data/Gen/GenerateEnumDataTableKey.h" #include "ProjectT/Data/Gen/GenerateStructLocalization.h" #include "ProjectT/System/Core/Settings/GameSettings/CoreGameUserSettings.h" bool UGlobalUtilsLibrary::IsValueInRange(const int32 Value, const int32 A, const int32 B, bool GreaterEqual, bool LessEqual) { bool G = GreaterEqual ? (Value >= A) : (Value > A); bool L = LessEqual ? (Value <= B) : (Value < B); return G && L; } UWorld* UGlobalUtilsLibrary::GetValidWorld(UObject* Object) { UWorld* World = Object->GetWorld(); NMT_CHECKF(World); return World; } UDataDam* UGlobalUtilsLibrary::GetSharedDataDam(UObject* Object) { NMT_CHECKF(Object); UWorld* World = GetValidWorld(Object); NMT_CHECKF(World); UGameInstance* GI = UGameplayStatics::GetGameInstance(World); NMT_CHECKF(GI); UDataDam* Ret = IGlobalObjectProvider::Execute_GetDataDam(GI); NMT_CHECKF(Ret); return Ret; } UStageManager* UGlobalUtilsLibrary::GetSharedLevelManager(UObject* Object) { NMT_CHECKF(Object); UWorld* World = GetValidWorld(Object); NMT_CHECKF(World); UGameInstance* GI = UGameplayStatics::GetGameInstance(World); NMT_CHECKF(GI); UStageManager* Ret = IGlobalObjectProvider::Execute_GetStageManager(GI); NMT_CHECKF(Ret); return Ret; } UOptionManager* UGlobalUtilsLibrary::GetSharedOptionManager(UObject* Object) { NMT_CHECKF(Object); UWorld* World = GetValidWorld(Object); NMT_CHECKF(World); UGameInstance* GI = UGameplayStatics::GetGameInstance(World); NMT_CHECKF(GI); UOptionManager* Ret = IGlobalObjectProvider::Execute_GetOptionManager(GI); NMT_CHECKF(Ret); return Ret; } USoundManager* UGlobalUtilsLibrary::GetSharedSoundManager(UObject* Object) { NMT_CHECKF(Object); UWorld* World = GetValidWorld(Object); NMT_CHECKF(World); UGameInstance* GI = UGameplayStatics::GetGameInstance(World); NMT_CHECKF(GI); USoundManager* Ret = IGlobalObjectProvider::Execute_GetSoundManager(GI); NMT_CHECKF(Ret); return Ret; } UCoreCheatManager* UGlobalUtilsLibrary::GetSharedCoreCheatManager(UObject* Object) { NMT_CHECKF(Object); UWorld* World = GetValidWorld(Object); NMT_CHECKF(World); UGameInstance* GI = UGameplayStatics::GetGameInstance(World); NMT_CHECKF(GI); UCoreCheatManager* Ret = IGlobalObjectProvider::Execute_GetCoreCheatManager(GI); NMT_CHECKF(Ret); return Ret; } UNotificationCenter* UGlobalUtilsLibrary::GetSharedNotificationCenter(UObject* Object) { NMT_CHECKF(Object); UWorld* World = GetValidWorld(Object); NMT_CHECKF(World); UGameInstance* GI = UGameplayStatics::GetGameInstance(World); NMT_CHECKF(GI); UNotificationCenter* Ret = IGlobalObjectProvider::Execute_GetNotificationCenter(GI); NMT_CHECKF(Ret); return Ret; } bool UGlobalUtilsLibrary::IsStandalonePlay(UObject* Object) { NMT_CHECKF(Object); ENetMode NetMode = Object->GetWorld()->GetNetMode(); return NetMode == NM_Standalone; } TArray UGlobalUtilsLibrary::ParseStringIndices(const TCHAR* Delimiter, const FString& Indices) { TArray Ret; Indices.ParseIntoArray(Ret, TEXT(";")); return Ret; } FString UGlobalUtilsLibrary::GetScriptTypeByRefPath(const FString& RefPath) { FString Ret; if (RefPath.Split(TEXT("."), nullptr, &Ret)) Ret.Split(TEXT("'"), &Ret, nullptr); return Ret; } EContentType UGlobalUtilsLibrary::GetContentTypeFromIndex(FName InRowName) { FString RowString = InRowName.ToString(); FString SliceString = DivideString(2, RowString); int32 ContentTypeNumber = FCString::Atoi(*SliceString); return StaticCast(ContentTypeNumber); } TArray UGlobalUtilsLibrary::ParseStringIndices(const FString& Indices, const FString& Delimeter) { TArray Ret; Indices.ParseIntoArray(Ret, *Delimeter); return Ret; } TArray UGlobalUtilsLibrary::GetFilteredCurrentActors(const TArray& InActors, const TArray& IgnoreClasses, const TArray& IncludeClasses) { bool bActorSubclass = false; bool bInterfaceClass = false; for (UClass* Class : IgnoreClasses) { bActorSubclass = Class->IsChildOf(AActor::StaticClass()); bInterfaceClass = Class->IsChildOf(UInterface::StaticClass()); NMT_MSG_CHECKF(bActorSubclass || bInterfaceClass, "%s Contains a class that isn’t allowed: %s", TEXT("IgnoreClasses"), *Class->GetName()); } for (UClass* Class : IncludeClasses) { bActorSubclass = Class->IsChildOf(AActor::StaticClass()); bInterfaceClass = Class->IsChildOf(UInterface::StaticClass()); NMT_MSG_CHECKF(bActorSubclass || bInterfaceClass, "%s Contains a class that isn’t allowed: %s", TEXT("IncludeClasses"), *Class->GetName()); } TArray::ElementType> Ret = InActors.FilterByPredicate([&IgnoreClasses, &IncludeClasses](const AActor* Actor) { UClass* CurrentActorClass = Actor->GetClass(); if(IgnoreClasses.Contains(CurrentActorClass)) return false; for(UClass* Class : IgnoreClasses) { if(Actor->IsA(Class)) return false; if(CurrentActorClass->ImplementsInterface(Class)) return false; } if(IncludeClasses.Num() == 0) return true; if(IncludeClasses.Contains(CurrentActorClass)) return true; for(UClass* Class : IncludeClasses) { if(Actor->IsA(Class)) return true; if(CurrentActorClass->ImplementsInterface(Class)) return true; } return false; }); return Ret; } FString UGlobalUtilsLibrary::ReferencePathToFilePath(const FString& ReferencePath) { FString Ret, Str; ReferencePath.Split("\'", nullptr, &Str); Str.Split(".", &Ret, nullptr); return Ret; } FString UGlobalUtilsLibrary::Uint32ToBase64String(uint32 Value) { const FString Alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!@"; FString Result = ""; if (Value == 0) Result = Alphabet.Mid(0, 1); for (int i = 1; i < 6; i++) { uint32 Index = Value % Alphabet.Len(); Result = Alphabet.Mid(Index, 1) + Result; Value = Value / Alphabet.Len(); } return Result; } TSoftClassPtr UGlobalUtilsLibrary::GetSoftWidgetClassFromPath(FString Path) { return GetStringToSoftClass(Path); } bool UGlobalUtilsLibrary::IsEditorPlay() { #if WITH_EDITOR return true; #else return false; #endif } void UGlobalUtilsLibrary::EnableComponent(UActorComponent* Component, bool bEnable) { NMT_CHECKF(Component); Component->SetComponentTickEnabled(bEnable); if (UPrimitiveComponent* PrimitiveComponent = Cast(Component)) { PrimitiveComponent->SetVisibility(bEnable, true); PrimitiveComponent->SetHiddenInGame(!bEnable, true); PrimitiveComponent->SetCollisionEnabled(bEnable ? ECollisionEnabled::QueryAndPhysics : ECollisionEnabled::NoCollision); } } FString UGlobalUtilsLibrary::GetLocalizedStringFromTable(const FName& TableRow) { UWorld* World = GEngine->GameViewport->GetWorld(); if (!World) return FString(); UDataDam* DD = GetSharedDataDam(World); NMT_CHECKF(DD); const UDataTable* LocalizeDT = DD->GetDataTableByEnum(EDataTableKey::Localization); FLocalization* LocalizeST = LocalizeDT->FindRow(TableRow, LocalizeDT->GetName()); if (!LocalizeST) return FString(); UCoreGameUserSettings* UserSetting = UCoreGameUserSettings::GetCoreGameUserSettings(); EGameLanguage CurLanguage = UserSetting->GetGamePlayOption().Setting_Language; FString OutputString = FString(); switch (CurLanguage) { case EGameLanguage::Korea: { OutputString = LocalizeST->sKorean; break; } case EGameLanguage::English: { OutputString = LocalizeST->sEnglish; break; } default: { OutputString = LocalizeST->sEnglish; break; } } return OutputString; } /*NOTE: 베지에 곡선의 드 카스텔조 알고리즘을 사용하여 주어진 제어점 Points에 대한 시간 t에서의 보정위치를 구한다. Points 배열의 첫번째 인덱스에는 시작점, 마지막 인덱스에는 끝점이 위치해야 한다. */ FVector UGlobalUtilsLibrary::GetBezierPointByDeCasteljau(const TArray& Points, float t) { if(Points.Num() == 1) return Points[0]; TArray NextLevel; for(int i = 0; i < Points.Num() - 1; ++i) { FVector LerpPoint = FMath::Lerp(Points[i], Points[i + 1], t); NextLevel.Add(LerpPoint); } return GetBezierPointByDeCasteljau(NextLevel, t); } // FIXME: 프로젝트 이주로 기존에 쓰던 데이터는 삭제됨 새로운 데이터 구조에 맞춰서 수정필요 int32 UGlobalUtilsLibrary::GetEnumIndexFromString(EDataTableKey InEnum, FString InString) { int32 Ret = 0; FString FindEnumType = "E" + EnumToString(InEnum); UEnum* EnumPtr = FindFirstObjectSafe(*FindEnumType); if (EnumPtr == nullptr) return Ret; { Ret = EnumPtr->GetIndexByNameString(InString); return Ret; } } FVector UGlobalUtilsLibrary::GetCenterPointBetweenTwoVectors(FVector A, FVector B) { return (A + B) * 0.5f; } double UGlobalUtilsLibrary::FindAngleBetweenTwoVectors2D(FVector2D A, FVector2D B) { A.Normalize(); B.Normalize(); double Scalar = A | B; double Angle = UKismetMathLibrary::DegAcos(Scalar); Angle = (A ^ B) > 0 ? Angle : Angle * -1.0; return Angle; } double UGlobalUtilsLibrary::FindAngleBetweenTwoVectors3D(FVector A, FVector B, EFindAngleAxis EFindAxis) { A.Normalize(); B.Normalize(); double Scalar = A | B; double Angle = UKismetMathLibrary::DegAcos(Scalar); FVector CrossVector = A ^ B; switch (EFindAxis) { case EFindAngleAxis::EForward: Angle = CrossVector.X > 0 ? Angle : Angle * -1.0; break; case EFindAngleAxis::EUp: Angle = CrossVector.Z > 0 ? Angle : Angle * -1.0; break; case EFindAngleAxis::ERight: Angle = CrossVector.Y > 0 ? Angle : Angle * -1.0; break; } return Angle; } bool UGlobalUtilsLibrary::SuggestProjectileVelocityAtLocation(const UObject* WorldContextObject, FVector& OutLaunchVelocity, const FVector& ProjectileStartLocation, const FVector& TargetLocation, const float DesiredArcHeight, double GravityZOverride, double TimeToTarget) { if (!GEngine) return false; if (TargetLocation == FVector::ZeroVector) return false; const UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); if (!World) return false; const double Gravity = FMath::IsNearlyZero(GravityZOverride) ? World->GetGravityZ() : GravityZOverride; const double StartZ = ProjectileStartLocation.Z; const double TargetZ = TargetLocation.Z; const double ApexZ = TargetZ + DesiredArcHeight; if (ApexZ <= StartZ || ApexZ <= TargetZ) return false; const double Sqrt = FMath::Sqrt(2.0 * FMath::Abs(Gravity) * (ApexZ - StartZ)); const double Up = Sqrt / FMath::Abs(Gravity); const double Down = FMath::Sqrt(2.0 * (ApexZ - TargetZ) / FMath::Abs(Gravity)); const double Time = Up + Down; const FVector Delta = TargetLocation - ProjectileStartLocation; const FVector DeltaXY = FVector(Delta.X, Delta.Y, 0.0); const FVector VelXY = DeltaXY / Time; OutLaunchVelocity = FVector(VelXY.X, VelXY.Y, Sqrt); return true; } // EX: (X=0.0000,Y=0.0000,Z=0.0000) -> FVector3D FVector UGlobalUtilsLibrary::StringToVector3D(FString& InString) { FString S = InString.Mid(1, InString.Len() - 2); TArray ParseString; S.ParseIntoArray(ParseString, TEXT(",")); NMT_MSG_CHECKF(ParseString.Num() == 3, "String Vector Has Fewer Than Three Elements"); float X = FCString::Atod(*ParseString[0] + 2); float Y = FCString::Atod(*ParseString[1] + 2); float Z = FCString::Atod(*ParseString[2] + 2); FVector Ret = FVector(X, Y, Z); return Ret; } FString UGlobalUtilsLibrary::DivideString(const int Count, FString& InString) { if (InString.Len() < Count) return FString(); FString Ret = InString.Left(Count); InString.RemoveAt(0, Count); return Ret; } void UGlobalUtilsLibrary::DebugBreak(const FString& MessageString) { checkf(0, TEXT("%s"), *MessageString); }