├── LICENSE ├── NativeFunctionLibrary.uplugin ├── README.md ├── Resources └── Icon128.png └── Source └── NativeFunctionLibrary ├── NativeFunctionLibrary.Build.cs ├── Private ├── NativeFunctionLibrary.cpp └── NativeFunctionLibraryBPLibrary.cpp └── Public ├── NativeFunctionLibrary.h └── NativeFunctionLibraryBPLibrary.h /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 jawadato 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /NativeFunctionLibrary.uplugin: -------------------------------------------------------------------------------- 1 | { 2 | "FileVersion": 3, 3 | "Version": 103, 4 | "VersionName": "1.3.0", 5 | "FriendlyName": "Native Function Library", 6 | "Description": "Some additional Blueprint functions.", 7 | "Category": "Jawadato", 8 | "CreatedBy": "Jawadato", 9 | "CreatedByURL": "https://www.jawadato.com", 10 | "DocsURL": "https://jawadato.github.io/native-function-library-docs", 11 | "MarketplaceURL": "com.epicgames.launcher://ue/marketplace/product/0665044cc8064063984a7155646595a8", 12 | "SupportURL": "https://github.com/jawadato/native-function-library", 13 | "CanContainContent": false, 14 | "Installed": true, 15 | "Modules": [ 16 | { 17 | "Name": "NativeFunctionLibrary", 18 | "Type": "Runtime", 19 | "LoadingPhase": "PreLoadingScreen" 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Native Function Library 2 | 3 | A handful of additional functions for Unreal Engine. Documentation and usage instructions below. 4 | 5 | ![nflb_fab_scrn_functions_000](https://github.com/user-attachments/assets/3bc612bd-6845-4238-9e39-3782a41707ae) 6 | 7 | # From Release 8 | 9 | - Grab the prebuilt plugin from the [Unreal Marketplace](https://www.unrealengine.com/marketplace/en-US/profile/jawadato). 10 | - Install the plugin to your engine then enable it in your project. 11 | - Search for the function names in a Blueprint graph and they should appear. 12 | 13 | # From Source 14 | 15 | - Create a new UE project. 16 | - Add the plugin into the Plugins directory of the newly created project. Open the uproject file and let the Editor compile the plugin using the VS build tools installed on your system. 17 | - For engine versions 5 and above, if you are relying on the Editor to compile the code then you may want to check the “Force Compilation at Startup” from the editor preferences otherwise you may need to manually compile the code every time you open the project. 18 | 19 | # Example Project 20 | 21 | - An [Example Project](https://jawadato.itch.io/native-function-library-example) is available. 22 | - Place the plugin into the Plugins folder of the project or simply enable it in the project's plugin settings if using Marketplace version. 23 | - Project is compatible with engine versions 5.3 and higher. 24 | 25 | ![nflb_uemp_scrn_001](https://github.com/user-attachments/assets/c574f41d-326f-4cc7-83f2-21c2d268f94b) 26 | 27 | # Documentation 28 | 29 | Documentation available [here](https://jawadato.github.io/native-function-library-docs). 30 | 31 | # Discord 32 | 33 | Discord server available [here](https://discord.gg/mGbAhp56JX). 34 | -------------------------------------------------------------------------------- /Resources/Icon128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jawadato/native-function-library/50cdcf3fc707d968896ea309d414385ab2b6a0a7/Resources/Icon128.png -------------------------------------------------------------------------------- /Source/NativeFunctionLibrary/NativeFunctionLibrary.Build.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 jawadato 2 | 3 | using UnrealBuildTool; 4 | 5 | public class NativeFunctionLibrary : ModuleRules 6 | { 7 | public NativeFunctionLibrary(ReadOnlyTargetRules Target) : base(Target) 8 | { 9 | PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; 10 | 11 | PublicIncludePaths.AddRange( 12 | new string[] 13 | { 14 | // ... add public include paths required here ... 15 | } 16 | ); 17 | 18 | 19 | PrivateIncludePaths.AddRange( 20 | new string[] 21 | { 22 | // ... add other private include paths required here ... 23 | } 24 | ); 25 | 26 | 27 | PublicDependencyModuleNames.AddRange( 28 | new string[] 29 | { 30 | "Core", 31 | "InputCore" 32 | } 33 | ); 34 | 35 | 36 | PrivateDependencyModuleNames.AddRange( 37 | new string[] 38 | { 39 | "CoreUObject", 40 | "Engine", 41 | "Slate", 42 | "SlateCore", 43 | "ApplicationCore" 44 | } 45 | ); 46 | 47 | 48 | DynamicallyLoadedModuleNames.AddRange( 49 | new string[] 50 | { 51 | // ... add any modules that your module loads dynamically here ... 52 | } 53 | ); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Source/NativeFunctionLibrary/Private/NativeFunctionLibrary.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 jawadato 2 | 3 | #include "NativeFunctionLibrary.h" 4 | 5 | #define LOCTEXT_NAMESPACE "FNativeFunctionLibraryModule" 6 | 7 | void FNativeFunctionLibraryModule::StartupModule() 8 | { 9 | // This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module 10 | 11 | } 12 | 13 | void FNativeFunctionLibraryModule::ShutdownModule() 14 | { 15 | // This function may be called during shutdown to clean up your module. For modules that support dynamic reloading, 16 | // we call this function before unloading the module. 17 | 18 | } 19 | 20 | #undef LOCTEXT_NAMESPACE 21 | 22 | IMPLEMENT_MODULE(FNativeFunctionLibraryModule, NativeFunctionLibrary) -------------------------------------------------------------------------------- /Source/NativeFunctionLibrary/Private/NativeFunctionLibraryBPLibrary.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 jawadato 2 | 3 | #include "NativeFunctionLibraryBPLibrary.h" 4 | #include "NativeFunctionLibrary.h" 5 | 6 | 7 | UNativeFunctionLibraryBPLibrary::UNativeFunctionLibraryBPLibrary(const FObjectInitializer& ObjectInitializer) 8 | : Super(ObjectInitializer) 9 | { 10 | 11 | } 12 | 13 | //MARK: SortActorsByDistance 14 | void UNativeFunctionLibraryBPLibrary::SortActorsByDistance(AActor* RelativeTo, TArray Array, TArray& ReturnValue) 15 | { 16 | Array.Sort([RelativeTo](const AActor& A, const AActor& B) 17 | { 18 | float DistanceA = A.GetSquaredDistanceTo(RelativeTo); 19 | float DistanceB = B.GetSquaredDistanceTo(RelativeTo); 20 | 21 | return DistanceA < DistanceB; 22 | }); 23 | 24 | ReturnValue = Array; 25 | } 26 | 27 | 28 | //MARK: SortActorsByDistance2D 29 | void UNativeFunctionLibraryBPLibrary::SortActorsByDistance2D(AActor* RelativeTo, TArray Array, TArray& ReturnValue) 30 | { 31 | Array.Sort([RelativeTo](const AActor& A, const AActor& B) 32 | { 33 | float DistanceA = A.GetHorizontalDistanceTo(RelativeTo); 34 | float DistanceB = B.GetHorizontalDistanceTo(RelativeTo); 35 | 36 | return DistanceA < DistanceB; 37 | }); 38 | 39 | ReturnValue = Array; 40 | } 41 | 42 | 43 | //MARK: SortActorsByLocation 44 | void UNativeFunctionLibraryBPLibrary::SortActorsByLocation(FVector RelativeTo, TArray Array, TArray& ReturnValue) 45 | { 46 | Array.Sort([RelativeTo](const AActor& A, const AActor& B) 47 | { 48 | float DistanceA = (A.GetActorLocation() - RelativeTo).Size(); 49 | float DistanceB = (B.GetActorLocation() - RelativeTo).Size(); 50 | 51 | return DistanceA < DistanceB; 52 | }); 53 | 54 | ReturnValue = Array; 55 | } 56 | 57 | 58 | //MARK: SortVectorsByDistance 59 | void UNativeFunctionLibraryBPLibrary::SortVectorsByDistance(FVector RelativeTo, TArray Array, TArray& ReturnValue) 60 | { 61 | Array.Sort([RelativeTo](const FVector& A, const FVector& B) 62 | { 63 | float DistanceA = FVector::DistSquared(A, RelativeTo); 64 | float DistanceB = FVector::DistSquared(B, RelativeTo); 65 | 66 | return DistanceA < DistanceB; 67 | }); 68 | 69 | ReturnValue = Array; 70 | } 71 | 72 | 73 | //MARK: RandomVectorsInExtent 74 | void UNativeFunctionLibraryBPLibrary::RandomVectorsInBoxExtent(int32 Amount, FVector InBoxExtent, FVector Origin, TArray& ReturnValue) 75 | { 76 | TArray Vectors; 77 | 78 | for (int32 i = 0; i < Amount; ++i) 79 | { 80 | FVector Vector; 81 | Vector.X = FMath::RandRange(-InBoxExtent.X, InBoxExtent.X); 82 | Vector.Y = FMath::RandRange(-InBoxExtent.Y, InBoxExtent.Y); 83 | Vector.Z = FMath::RandRange(-InBoxExtent.Z, InBoxExtent.Z); 84 | Vectors.Add(Vector + Origin); 85 | } 86 | 87 | ReturnValue = Vectors; 88 | } 89 | 90 | 91 | //MARK: RandomVectorsInExtentFromStream 92 | void UNativeFunctionLibraryBPLibrary::RandomVectorsInBoxExtentFromStream(int32 Amount, FVector InBoxExtent, FVector Origin, FRandomStream Stream, TArray& ReturnValue) 93 | { 94 | TArray Vectors; 95 | 96 | for (int32 i = 0; i < Amount; ++i) 97 | { 98 | FVector Vector; 99 | Vector.X = Stream.FRandRange(-InBoxExtent.X, InBoxExtent.X); 100 | Vector.Y = Stream.FRandRange(-InBoxExtent.Y, InBoxExtent.Y); 101 | Vector.Z = Stream.FRandRange(-InBoxExtent.Z, InBoxExtent.Z); 102 | Vectors.Add(Vector + Origin); 103 | } 104 | 105 | ReturnValue = Vectors; 106 | } 107 | 108 | 109 | //MARK: AverageSeparationBetweenVectors 110 | void UNativeFunctionLibraryBPLibrary::AverageSeparationBetweenVectors(TArray Array, float& ReturnValue) 111 | { 112 | float TotalDistance = 0.f; 113 | const int32 NumVectors = Array.Num(); 114 | for (int32 i = 0; i < NumVectors; ++i) 115 | { 116 | for (int32 j = i + 1; j < NumVectors; ++j) 117 | { 118 | const FVector& VectorI = Array[i]; 119 | const FVector& VectorJ = Array[j]; 120 | const float Distance = FVector::Dist(VectorI, VectorJ); 121 | 122 | TotalDistance += Distance; 123 | } 124 | } 125 | 126 | ReturnValue = (TotalDistance / (NumVectors * (NumVectors - 1))) * 2; 127 | } 128 | 129 | 130 | //MARK: NotNearLocations 131 | bool UNativeFunctionLibraryBPLibrary::NotNearLocations(FVector RelativeTo, TArray Array, float Radius) 132 | { 133 | bool bNotInRadius = true; 134 | float CurrentRadius = 0.f; 135 | 136 | for (FVector& Position : Array) 137 | { 138 | CurrentRadius = FVector::Dist(Position, RelativeTo); 139 | if (CurrentRadius <= Radius) 140 | { 141 | bNotInRadius = false; 142 | break; 143 | } 144 | }; 145 | 146 | return bNotInRadius; 147 | } 148 | 149 | 150 | //MARK: PutAllRigidBodiesToSleep 151 | void UNativeFunctionLibraryBPLibrary::PutAllRigidBodiesToSleep(USkeletalMeshComponent* Mesh) 152 | { 153 | if (!Mesh) 154 | { 155 | return; 156 | } 157 | 158 | Mesh->PutAllRigidBodiesToSleep(); 159 | 160 | return; 161 | } 162 | 163 | 164 | //MARK: ClearOnScreenDebugMessages 165 | void UNativeFunctionLibraryBPLibrary::ClearOnScreenDebugMessages() 166 | { 167 | GEngine->ClearOnScreenDebugMessages(); 168 | } 169 | 170 | 171 | //MARK: LaunchedWithCommandLineArgument 172 | bool UNativeFunctionLibraryBPLibrary::LaunchedWithCommandLineArgument(FString Argument) 173 | { 174 | return FParse::Param(FCommandLine::Get(), *Argument); 175 | } 176 | 177 | 178 | //MARK: StringToClipboard 179 | void UNativeFunctionLibraryBPLibrary::StringToClipboard(const FString& String) 180 | { 181 | FPlatformApplicationMisc::ClipboardCopy(*String); 182 | } 183 | 184 | 185 | //MARK: ClipboardToString 186 | FString UNativeFunctionLibraryBPLibrary::ClipboardToString() 187 | { 188 | FString String; 189 | 190 | FPlatformApplicationMisc::ClipboardPaste(String); 191 | 192 | return String; 193 | } 194 | 195 | //MARK: GetWorldObjectCount 196 | int32 UNativeFunctionLibraryBPLibrary::GetWorldObjectCount(UObject* WorldContext) 197 | { 198 | int32 Count = 0; 199 | 200 | for (TObjectIterator ObjectIterator; ObjectIterator; ++ObjectIterator) 201 | { 202 | if (ObjectIterator->GetWorld() == WorldContext ->GetWorld()) 203 | { 204 | UObject* ObjectModel = *ObjectIterator; 205 | Count ++; 206 | } 207 | } 208 | 209 | return Count; 210 | } 211 | 212 | 213 | //MARK: HexToColor 214 | FColor UNativeFunctionLibraryBPLibrary::HexToColor(FString Hex) 215 | { 216 | return FColor::FromHex(Hex); 217 | } 218 | 219 | 220 | //MARK: ColorToHex 221 | FString UNativeFunctionLibraryBPLibrary::ColorToHex(FColor Color) 222 | { 223 | return Color.ToHex(); 224 | } 225 | 226 | 227 | //MARK: StringToFile 228 | bool UNativeFunctionLibraryBPLibrary::StringToFile(FString String, const FString Filename) 229 | { 230 | const TCHAR* FilePath = *Filename; 231 | 232 | return FFileHelper::SaveStringToFile(String, FilePath); 233 | } 234 | 235 | 236 | //MARK: StringArrayToFile 237 | bool UNativeFunctionLibraryBPLibrary::StringArrayToFile(const TArray& Strings, const FString Filename) 238 | { 239 | const TCHAR* FilePath = *Filename; 240 | 241 | return FFileHelper::SaveStringArrayToFile(Strings, FilePath); 242 | } 243 | 244 | 245 | //MARK: FileToString 246 | bool UNativeFunctionLibraryBPLibrary::FileToString(FString& String, const FString Filename) 247 | { 248 | const TCHAR* FilePath = *Filename; 249 | 250 | return FFileHelper::LoadFileToString(String, FilePath); 251 | } 252 | 253 | 254 | //MARK: FileToStringArray 255 | bool UNativeFunctionLibraryBPLibrary::FileToStringArray(TArray& Strings, const FString Filename) 256 | { 257 | const TCHAR* FilePath = *Filename; 258 | 259 | return FFileHelper::LoadFileToStringArray(Strings, FilePath); 260 | } 261 | 262 | 263 | //MARK: StringArrayToSorted 264 | TArray UNativeFunctionLibraryBPLibrary::StringArrayToSorted(const TArray& Strings) 265 | { 266 | TArray SortedArray = Strings; 267 | SortedArray.Sort(); 268 | return SortedArray; 269 | } 270 | 271 | 272 | //MARK: IntegerArrayToSorted 273 | TArray UNativeFunctionLibraryBPLibrary::IntegerArrayToSorted(const TArray& Integers) 274 | { 275 | TArray SortedArray = Integers; 276 | SortedArray.Sort(); 277 | return SortedArray; 278 | } 279 | 280 | 281 | //MARK: FloatArrayToSorted 282 | TArray UNativeFunctionLibraryBPLibrary::FloatArrayToSorted(const TArray& Floats) 283 | { 284 | TArray SortedArray = Floats; 285 | SortedArray.Sort(); 286 | return SortedArray; 287 | } 288 | 289 | 290 | //MARK: CalculateMean 291 | float UNativeFunctionLibraryBPLibrary::CalculateMean(const TArray& Data) 292 | { 293 | int32 NumberOfElements = Data.Num(); 294 | 295 | if (NumberOfElements > 0) 296 | { 297 | float TotalValue = 0.f; 298 | 299 | for (int32 i = 0; i < NumberOfElements; ++i) 300 | { 301 | TotalValue += Data[i]; 302 | } 303 | 304 | return TotalValue / NumberOfElements; 305 | } 306 | else 307 | { 308 | return 0.f; 309 | } 310 | } 311 | 312 | 313 | //MARK: CalculateWeightedMean 314 | float UNativeFunctionLibraryBPLibrary::CalculateWeightedMean(const TArray& Data, const TArray& Weights) 315 | { 316 | int32 NumberOfWeightElements = Weights.Num(); 317 | int32 NumberOfDataElements = Data.Num(); 318 | float Divisor = 0.f; 319 | 320 | if ((NumberOfDataElements > 0) && (NumberOfWeightElements == NumberOfDataElements)) 321 | { 322 | float TotalValue = 0.f; 323 | 324 | for (int32 i = 0; i < NumberOfDataElements; ++i) 325 | { 326 | TotalValue += (Data[i] * Weights[i]); 327 | } 328 | for (int32 i = 0; i < NumberOfDataElements; ++i) 329 | { 330 | Divisor += Weights[i]; 331 | } 332 | 333 | return TotalValue / Divisor; 334 | } 335 | else 336 | { 337 | return 0.f; 338 | } 339 | } 340 | 341 | 342 | //MARK: CalculateMedian 343 | float UNativeFunctionLibraryBPLibrary::CalculateMedian(const TArray& Data) 344 | { 345 | TArray SortedData = Data; 346 | 347 | SortedData.Sort(); 348 | 349 | int32 NumberOfElements = SortedData.Num(); 350 | float MedianValue = 0.f; 351 | 352 | if (NumberOfElements > 1) 353 | { 354 | bool bIsEven = false; 355 | 356 | if (NumberOfElements % 2 == 0) 357 | { 358 | bIsEven = true; 359 | } 360 | 361 | if (bIsEven) 362 | { 363 | int32 IndexA = NumberOfElements / 2; 364 | int32 IndexB = IndexA - 1; 365 | 366 | MedianValue = (SortedData[IndexA] + SortedData[IndexB]) / 2; 367 | } 368 | else 369 | { 370 | int32 MedianIndex = (NumberOfElements - 1) / 2; 371 | 372 | MedianValue = SortedData[MedianIndex]; 373 | } 374 | } 375 | 376 | return MedianValue; 377 | } 378 | 379 | 380 | //MARK: CalculateStatisticalRange 381 | float UNativeFunctionLibraryBPLibrary::CalculateStatisticalRange(const TArray& Data) 382 | { 383 | if (Data.Num() > 1) 384 | { 385 | return FMath::Max(Data) - FMath::Min(Data); 386 | } 387 | else 388 | { 389 | return 0.f; 390 | } 391 | } 392 | 393 | 394 | //MARK: CalculateStandardDeviation 395 | float UNativeFunctionLibraryBPLibrary::CalculateStandardDeviation(bool bPopulation, const TArray& Data) 396 | { 397 | int32 n = Data.Num(); 398 | float x = 0.f; 399 | float XSquared = 0.f; 400 | float SquaredSum = 0.f; 401 | float Divisor = 0.f; 402 | 403 | for (int32 i = 0; i < n; ++i) 404 | { 405 | x += Data[i]; 406 | } 407 | 408 | XSquared = FMath::Square(x); 409 | 410 | for (int32 i = 0; i < n; ++i) 411 | { 412 | SquaredSum += FMath::Square(Data[i]); 413 | } 414 | 415 | if (bPopulation) 416 | { 417 | Divisor = FMath::Square(n); 418 | } 419 | else 420 | { 421 | Divisor = (n * (n - 1)); 422 | } 423 | 424 | return FMath::Sqrt(((n * SquaredSum) - XSquared) / Divisor); 425 | } 426 | 427 | 428 | //MARK: CalculateStatisticalZScore 429 | float UNativeFunctionLibraryBPLibrary::CalculateStatisticalZScore(float ObservedValue, float Mean, float StandardDeviation) 430 | { 431 | return (ObservedValue - Mean) / StandardDeviation; 432 | } 433 | 434 | 435 | //MARK: CalculateRelativeRisk 436 | float UNativeFunctionLibraryBPLibrary::CalculateRelativeRisk(float PopulationSize, float WithoutExposure, float WithExposure, bool bPercentage) 437 | { 438 | float RiskB = WithoutExposure / PopulationSize; 439 | float RiskA = WithExposure / PopulationSize; 440 | float RiskR = RiskA / RiskB; 441 | 442 | if (bPercentage) 443 | { 444 | return RiskR * 100; 445 | } 446 | else 447 | { 448 | return RiskR; 449 | } 450 | } 451 | 452 | 453 | //MARK: CalculateNumberOfPairs 454 | int32 UNativeFunctionLibraryBPLibrary::CalculateNumberOfPairs(int32 NumberOfElements) 455 | { 456 | if (NumberOfElements > 1) 457 | { 458 | int32 nX = NumberOfElements; 459 | int32 nY = nX - 1; 460 | 461 | return (nX * nY) / 2; 462 | } 463 | else 464 | { 465 | return 0; 466 | } 467 | } 468 | 469 | 470 | //MARK: CalculateLikelihood 471 | float UNativeFunctionLibraryBPLibrary::CalculateLikelihood(float Probability, int32 RepeatCount) 472 | { 473 | float p = 1.0f - Probability; 474 | 475 | if (RepeatCount > 0 && p > 0.f && p < 1.0f) 476 | { 477 | return 1.0f - (FMath::Pow(p, RepeatCount)); 478 | } 479 | else 480 | { 481 | return 1.0f - p; 482 | } 483 | } 484 | 485 | 486 | //MARK: FlushInputs 487 | void UNativeFunctionLibraryBPLibrary::FlushInputs(APlayerController* PlayerController) 488 | { 489 | PlayerController->FlushPressedKeys(); 490 | } 491 | 492 | 493 | //MARK: GetInputHeldDuration 494 | float UNativeFunctionLibraryBPLibrary::GetInputHeldDuration(APlayerController* PlayerController, FKey Key) 495 | { 496 | return PlayerController->GetInputKeyTimeDown(Key); 497 | } 498 | 499 | 500 | //MARK: GetHitResultAtScreenPosition 501 | bool UNativeFunctionLibraryBPLibrary::GetHitResultAtScreenPosition(APlayerController* PlayerController, const FVector2D ScreenPosition, const ETraceTypeQuery TraceChannel, bool bTraceComplex, FHitResult& HitResult) 502 | { 503 | return PlayerController->GetHitResultAtScreenPosition(ScreenPosition, TraceChannel, bTraceComplex, HitResult); 504 | } 505 | 506 | 507 | //MARK: ClientFadeCamera 508 | void UNativeFunctionLibraryBPLibrary::ClientFadeCamera(APlayerController* PlayerController, bool bFadeAudio, bool bHoldWhenFinished, FLinearColor FadeColor, float FadeAlphaStart, float FadeAlphaStop, float FadeDuration) 509 | { 510 | FColor ConvertedFadeColor = FadeColor.ToFColor(true); 511 | FVector2D FadeAlpha = FVector2D(FadeAlphaStart, FadeAlphaStop); 512 | 513 | PlayerController->ClientSetCameraFade(true, ConvertedFadeColor, FadeAlpha, FadeDuration, bFadeAudio, bHoldWhenFinished); 514 | } 515 | 516 | 517 | //MARK: LocationOnScreen 518 | bool UNativeFunctionLibraryBPLibrary::LocationOnScreen(APlayerController* PlayerController, FVector Location) 519 | 520 | { 521 | if (!GEngine && !PlayerController) 522 | { 523 | return false; 524 | } 525 | 526 | const FVector2D ViewportSize = FVector2D(GEngine->GameViewport->Viewport->GetSizeXY()); 527 | 528 | FVector CameraLocation; 529 | FRotator CameraRotation; 530 | 531 | PlayerController->GetPlayerViewPoint(CameraLocation, CameraRotation); 532 | 533 | const FVector Direction = Location - CameraLocation; 534 | FVector ForwardVector = CameraRotation.Vector(); 535 | FVector NormalizedDirection = Direction.GetSafeNormal(); 536 | 537 | float DotProduct = FVector::DotProduct(ForwardVector, NormalizedDirection); 538 | bool bBehindCamera = (DotProduct < 0); 539 | FVector2D ScreenPosition = FVector2D(); 540 | 541 | if (bBehindCamera) 542 | { 543 | FVector NewLocation = CameraLocation + Direction * -1.f; 544 | 545 | PlayerController->ProjectWorldLocationToScreen(NewLocation, ScreenPosition); 546 | 547 | ScreenPosition.X = ViewportSize.X - ScreenPosition.X; 548 | ScreenPosition.Y = ViewportSize.Y - ScreenPosition.Y; 549 | } 550 | else 551 | { 552 | PlayerController->ProjectWorldLocationToScreen(Location, ScreenPosition); 553 | } 554 | 555 | if (ScreenPosition.X >= 0.f && ScreenPosition.X <= ViewportSize.X && ScreenPosition.Y >= 0.f && ScreenPosition.Y <= ViewportSize.Y && !bBehindCamera) 556 | { 557 | return true; 558 | } 559 | 560 | return false; 561 | } -------------------------------------------------------------------------------- /Source/NativeFunctionLibrary/Public/NativeFunctionLibrary.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 jawadato 2 | 3 | #pragma once 4 | 5 | #include "Modules/ModuleManager.h" 6 | 7 | class FNativeFunctionLibraryModule : public IModuleInterface 8 | { 9 | public: 10 | 11 | /** IModuleInterface implementation */ 12 | virtual void StartupModule() override; 13 | virtual void ShutdownModule() override; 14 | }; 15 | -------------------------------------------------------------------------------- /Source/NativeFunctionLibrary/Public/NativeFunctionLibraryBPLibrary.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 jawadato 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "UnrealClient.h" 7 | #include "Engine/Engine.h" 8 | #include "Engine/GameViewportClient.h" 9 | #include "Misc/FileHelper.h" 10 | #include "Misc/App.h" 11 | #include "Math/Color.h" 12 | #include "Components/SkeletalMeshComponent.h" 13 | #include "HAL/PlatformApplicationMisc.h" 14 | #include "UObject/UObjectIterator.h" 15 | #include "GameFramework/Actor.h" 16 | #include "GameFramework/PlayerController.h" 17 | #include "Kismet/BlueprintFunctionLibrary.h" 18 | #include "NativeFunctionLibraryBPLibrary.generated.h" 19 | 20 | 21 | UCLASS(Meta = (DisplayName = "Native Function Library")) 22 | class UNativeFunctionLibraryBPLibrary : public UBlueprintFunctionLibrary 23 | { 24 | GENERATED_UCLASS_BODY() 25 | 26 | //MARK: SortActorsByDistance 27 | /** 28 | * Sorts an array of actors relative to distance to the provided actor from closest to furthest. 29 | * @param RelativeTo Actor to sort against 30 | * @param Array Array to sort 31 | * @return Sorted Array from closest to furthest 32 | */ 33 | UFUNCTION(BlueprintCallable, Category = "Jawadato|NativeFunctionLibrary|Actor", Meta = (Keywords = "SortActorsByDistance")) 34 | static void SortActorsByDistance(AActor* RelativeTo, TArray Array, TArray& ReturnValue); 35 | 36 | 37 | //MARK: SortActorsByDistance2D 38 | /** 39 | * Sorts an array of actors relative to horizontal distance to the provided actor from closest to furthest. 40 | * @param RelativeTo Actor to sort against 41 | * @param Array Array to sort 42 | * @return Sorted Array from closest to furthest 43 | */ 44 | UFUNCTION(BlueprintCallable, Category = "Jawadato|NativeFunctionLibrary|Actor", Meta = (Keywords = "SortActorsByDistance2D")) 45 | static void SortActorsByDistance2D(AActor* RelativeTo, TArray Array, TArray& ReturnValue); 46 | 47 | 48 | //MARK: SortActorsByLocation 49 | /** 50 | * Sorts an array of actors relative to distance to the provided location vector from closest to furthest. 51 | * @param RelativeTo Location to sort against 52 | * @param Array Array to sort 53 | * @return Sorted Array from closest to furthest 54 | */ 55 | UFUNCTION(BlueprintCallable, Category = "Jawadato|NativeFunctionLibrary|Actor", Meta = (Keywords = "SortActorsByLocation")) 56 | static void SortActorsByLocation(FVector RelativeTo, TArray Array, TArray& ReturnValue); 57 | 58 | 59 | //MARK: SortVectorsByDistance 60 | /** 61 | * Sorts an array of vectors relative to distance to the provided location vector from closest to furthest. 62 | * @param RelativeTo Location to sort against 63 | * @param Array Array to sort 64 | * @return Sorted Array from closest to furthest 65 | */ 66 | UFUNCTION(BlueprintCallable, Category = "Jawadato|NativeFunctionLibrary|Vector", Meta = (Keywords = "SortVectorsByDistance")) 67 | static void SortVectorsByDistance(FVector RelativeTo, TArray Array, TArray& ReturnValue); 68 | 69 | 70 | //MARK: RandomVectorsInExtent 71 | /** 72 | * Returns an array of random vectors distributed within a certain box extent from the origin, counting up to the provided amount. 73 | * @param Amount Count of vectors 74 | * @param InBoxExtent Extent of the rectangular volume 75 | * @param Origin Origin of the volume 76 | * @return Created vectors 77 | */ 78 | UFUNCTION(BlueprintPure, Category = "Jawadato|NativeFunctionLibrary|Vector", Meta = (Keywords = "RandomVectorsInExtent")) 79 | static void RandomVectorsInBoxExtent(int32 Amount, FVector InBoxExtent, FVector Origin, TArray& ReturnValue); 80 | 81 | 82 | //MARK: RandomVectorsInExtentFromStream 83 | /** 84 | * Returns an array of random vectors distributed within a certain box extent from the origin, counting up to the provided amount. 85 | * @param Amount Count of vectors 86 | * @param InBoxExtent Extent of the rectangular volume 87 | * @param Origin Origin of the volume 88 | * @param Stream Random stream to use 89 | * @return Created vectors 90 | */ 91 | UFUNCTION(BlueprintPure, Category = "Jawadato|NativeFunctionLibrary|Vector", Meta = (Keywords = "RandomVectorsInExtentFromStream")) 92 | static void RandomVectorsInBoxExtentFromStream(int32 Amount, FVector InBoxExtent, FVector Origin, FRandomStream Stream, TArray& ReturnValue); 93 | 94 | 95 | //MARK: AverageSeparationBetweenVectors 96 | /** 97 | * Returns an arbitrary average separation value between an array of vectors, can be used to define arbitrary density of supplied vectors. 98 | * @param Array Array which contains the vectors 99 | * @return Calculated average separation value 100 | */ 101 | UFUNCTION(BlueprintPure, Category = "Jawadato|NativeFunctionLibrary|Vector", Meta = (Keywords = "AverageSeparationBetweenVectors")) 102 | static void AverageSeparationBetweenVectors(TArray Array, float& ReturnValue); 103 | 104 | 105 | //MARK: NotNearLocations 106 | /** 107 | * Compares an array of vectors against a provided location vector and returns true if none in the array is within a certain radius of the provided location vector. 108 | * @param RelativeTo Location vector to compare against 109 | * @param Array Array containing the vectors 110 | * @param Radius Radius within which to query 111 | * @return True or false based on query result 112 | */ 113 | UFUNCTION(BlueprintPure, Category = "Jawadato|NativeFunctionLibrary|Vector", Meta = (Keywords = "NotNearLocations")) 114 | static bool NotNearLocations(FVector RelativeTo, TArray Array, float Radius); 115 | 116 | 117 | //MARK: PutAllRigidBodiesToSleep 118 | /** 119 | * Force all bodies of associated skeletal mesh back to sleep. 120 | * @param Mesh Skeletal Mesh which contains the simulating bones 121 | */ 122 | UFUNCTION(BlueprintCallable, Category = "Jawadato|NativeFunctionLibrary|SkeletalMesh", Meta = (Keywords = "PutAllRigidBodiesToSleep")) 123 | static void PutAllRigidBodiesToSleep(USkeletalMeshComponent* Mesh); 124 | 125 | 126 | //MARK: ClearOnScreenDebugMessages 127 | /** 128 | * Clears all on screen debug messages. 129 | */ 130 | UFUNCTION(BlueprintCallable, Category = "Jawadato|NativeFunctionLibrary|Debug", Meta = (Keywords = "ClearOnScreenDebugMessages")) 131 | static void ClearOnScreenDebugMessages(); 132 | 133 | 134 | //MARK: LaunchedWithCommandLineArgument 135 | /** 136 | * Returns true if a specific command line flag was used during launch. 137 | * @param Argument Command line argument to query against 138 | * @return True or false based on query result 139 | */ 140 | UFUNCTION(BlueprintPure, Category = "Jawadato|NativeFunctionLibrary|CommandLine", Meta = (Keywords = "LaunchedWithCommandLineArgument")) 141 | static bool LaunchedWithCommandLineArgument(FString Argument = ""); 142 | 143 | 144 | //MARK: StringToClipboard 145 | /** 146 | * Copies the provided string into clipboard. 147 | * @param String String which to copy 148 | */ 149 | UFUNCTION(BlueprintCallable, Category = "Jawadato|NativeFunctionLibrary|Misc", Meta = (Keywords = "StringToClipboard")) 150 | static void StringToClipboard(const FString& String); 151 | 152 | 153 | //MARK: ClipboardToString 154 | /** 155 | * Retrieves the contents of the clipboard into a string. 156 | * @return String containing clipboard contents 157 | */ 158 | UFUNCTION(BlueprintCallable, Category = "Jawadato|NativeFunctionLibrary|Misc", Meta = (Keywords = "ClipboardToString")) 159 | static FString ClipboardToString(); 160 | 161 | 162 | //MARK: GetWorldObjectCount 163 | /** 164 | * Retrieves the number of UObjects present in the world. 165 | * @return UObject count 166 | */ 167 | UFUNCTION(BlueprintCallable, Category = "Jawadato|NativeFunctionLibrary|Misc", Meta = (Keywords = "GetWorldObjectCount", WorldContext = "WorldContext")) 168 | static int32 GetWorldObjectCount(UObject* WorldContext); 169 | 170 | 171 | //MARK: HexToColor 172 | /** 173 | * Converts provided Hex color code to a Color Structure. 174 | * @param Hex Hex code which to convert 175 | * @return Converted Color Structure 176 | */ 177 | UFUNCTION(BlueprintCallable, Category = "Jawadato|NativeFunctionLibrary|String", Meta = (Keywords = "HexToColor")) 178 | static FColor HexToColor(FString Hex); 179 | 180 | 181 | //MARK: ColorToHex 182 | /** 183 | * Converts provided Color Structure into Hex color code. 184 | * @param Color Color Structure which to convert 185 | * @return Converted Hex String 186 | */ 187 | UFUNCTION(BlueprintCallable, Category = "Jawadato|NativeFunctionLibrary|String", Meta = (Keywords = "ColorToHex")) 188 | static FString ColorToHex(FColor Color); 189 | 190 | 191 | //MARK: StringToFile 192 | /** 193 | * Writes provided String to a File. 194 | * @param String String which to save 195 | * @param Filename File path to use 196 | * @return Result of write operation 197 | */ 198 | UFUNCTION(BlueprintCallable, Category = "Jawadato|NativeFunctionLibrary|String", Meta = (Keywords = "StringToFile")) 199 | static bool StringToFile(FString String, const FString Filename); 200 | 201 | 202 | //MARK: StringArrayToFile 203 | /** 204 | * Writes provided String Array to a File. 205 | * @param Strings Strings to save 206 | * @param Filename File path to use 207 | * @return Result of write operation 208 | */ 209 | UFUNCTION(BlueprintCallable, Category = "Jawadato|NativeFunctionLibrary|String", Meta = (Keywords = "StringArrayToFile")) 210 | static bool StringArrayToFile(const TArray& Strings, const FString Filename); 211 | 212 | 213 | //MARK: FileToString 214 | /** 215 | * Loads provided File into a String. 216 | * @param String Loaded String 217 | * @param Filename File path to use 218 | * @return Result of read operation 219 | */ 220 | UFUNCTION(BlueprintCallable, Category = "Jawadato|NativeFunctionLibrary|String", Meta = (Keywords = "FileToString")) 221 | static bool FileToString(FString& String, const FString Filename); 222 | 223 | 224 | //MARK: FileToStringArray 225 | /** 226 | * Loads provided File into a String Array. 227 | * @param Strings Loaded Strings 228 | * @param Filename File path to use 229 | * @return Result of read operation 230 | */ 231 | UFUNCTION(BlueprintCallable, Category = "Jawadato|NativeFunctionLibrary|String", Meta = (Keywords = "FileToStringArray")) 232 | static bool FileToStringArray(TArray& Strings, const FString Filename); 233 | 234 | 235 | //MARK: StringArrayToSorted 236 | /** 237 | * Creates a copy of the provided String Array then sorts the copy in ascending order and returns the value. 238 | * @param Strings Strings to sort 239 | * @return Result of sort operation 240 | */ 241 | UFUNCTION(BlueprintCallable, Category = "Jawadato|NativeFunctionLibrary|String", Meta = (Keywords = "StringArrayToSorted")) 242 | static TArray StringArrayToSorted(const TArray& Strings); 243 | 244 | 245 | //MARK: IntegerArrayToSorted 246 | /** 247 | * Creates a copy of the provided Integer Array then sorts the copy in ascending order and returns the value. 248 | * @param Integers Integers to sort 249 | * @return Result of sort operation 250 | */ 251 | UFUNCTION(BlueprintCallable, Category = "Jawadato|NativeFunctionLibrary|Integer", Meta = (Keywords = "IntegerArrayToSorted")) 252 | static TArray IntegerArrayToSorted(const TArray& Integers); 253 | 254 | 255 | //MARK: FloatArrayToSorted 256 | /** 257 | * Creates a copy of the provided Float Array then sorts the copy in ascending order and returns the value. 258 | * @param Floats Floats to sort 259 | * @return Result of sort operation 260 | */ 261 | UFUNCTION(BlueprintCallable, Category = "Jawadato|NativeFunctionLibrary|Float", Meta = (Keywords = "FloatArrayToSorted")) 262 | static TArray FloatArrayToSorted(const TArray& Floats); 263 | 264 | 265 | //MARK: CalculateMean 266 | /** 267 | * Provided a dataset in form of a Float array, returns the Mean value. 268 | * @param Data Float array to find Mean value within 269 | * @return Mean value 270 | */ 271 | UFUNCTION(BlueprintCallable, Category = "Jawadato|NativeFunctionLibrary|Statistics", Meta = (Keywords = "CalculateMean")) 272 | static float CalculateMean(const TArray& Data); 273 | 274 | 275 | //MARK: CalculateWeightedMean 276 | /** 277 | * Provided two Float arrays, returns the Weighted Mean value. 278 | * Both arrays must consist of equal amount of entries. 279 | * Weights are mapped onto data based on matching indices. 280 | * @param Data Float array to find Weighted Mean value within 281 | * @param Weights Float array comprising of weights needed to evaluate the data 282 | * @return Weighted Mean value 283 | */ 284 | UFUNCTION(BlueprintCallable, Category = "Jawadato|NativeFunctionLibrary|Statistics", Meta = (Keywords = "CalculateWeightedMean")) 285 | static float CalculateWeightedMean(const TArray& Data, const TArray& Weights); 286 | 287 | 288 | //MARK: CalculateMedian 289 | /** 290 | * Provided a dataset in form of a Float array, returns the Median value. 291 | * @param Data Float array to find Median value within 292 | * @return Median value 293 | */ 294 | UFUNCTION(BlueprintCallable, Category = "Jawadato|NativeFunctionLibrary|Statistics", Meta = (Keywords = "CalculateMedian")) 295 | static float CalculateMedian(const TArray& Data); 296 | 297 | 298 | //MARK: CalculateStatisticalRange 299 | /** 300 | * Provided a dataset in form of a Float array, returns the Statistical Range value. 301 | * @param Data Float array to find Range value within 302 | * @return Range value 303 | */ 304 | UFUNCTION(BlueprintCallable, Category = "Jawadato|NativeFunctionLibrary|Statistics", Meta = (Keywords = "CalculateStatisticalRange")) 305 | static float CalculateStatisticalRange(const TArray& Data); 306 | 307 | 308 | //MARK: CalculateStandardDeviation 309 | /** 310 | * Provided a dataset in form of a Float array, returns the Standard Deviation value. 311 | * Optionally treat data as "Population" instead of "Sample". 312 | * @param bPopulation Set true to treat data as "Population"; treat as "Sample" otherwise 313 | * @param Data Float array to find Standard Deviation value within 314 | * @return Standard Deviation value 315 | */ 316 | UFUNCTION(BlueprintCallable, Category = "Jawadato|NativeFunctionLibrary|Statistics", Meta = (Keywords = "CalculateStandardDeviation")) 317 | static float CalculateStandardDeviation(bool bPopulation, const TArray& Data); 318 | 319 | 320 | //MARK: CalculateStatisticalZScore 321 | /** 322 | * Provided an Observed Value along with the Mean and Standard Deviation of a dataset, returns the Standard Score (Z-Score). 323 | * @param ObservedValue Value to find Z-Score for 324 | * @param Mean Mean value 325 | * @param StandardDeviation Standard Deviation value 326 | * @return Z-Score 327 | */ 328 | UFUNCTION(BlueprintCallable, Category = "Jawadato|NativeFunctionLibrary|Statistics", Meta = (DisplayName = "Calculate Statistical Z-Score", Keywords = "CalculateStatisticalZScore")) 329 | static float CalculateStatisticalZScore(float ObservedValue, float Mean, float StandardDeviation); 330 | 331 | 332 | //MARK: CalculateRelativeRisk 333 | /** 334 | * Provided a population size, how many develop a risk without exposure and how many do, returns the relative risk. 335 | * Optionally multiply by 100 to return the percentage figure. 336 | * @param PopulationSize Size of the population 337 | * @param WithoutExposure Subset of population without exposure or placebo (background) Subset 338 | * @param WithExposure Subset of population with exposure 339 | * @param bPercentage Multiply by 100 340 | * @return Relative risk 341 | */ 342 | UFUNCTION(BlueprintCallable, Category = "Jawadato|NativeFunctionLibrary|Statistics", Meta = (Keywords = "CalculateRelativeRisk")) 343 | static float CalculateRelativeRisk(float PopulationSize, float WithoutExposure, float WithExposure, bool bPercentage); 344 | 345 | 346 | //MARK: CalculateNumberOfPairs 347 | /** 348 | * Provided the size of a finite set of elements, returns the number of pairs of elements. 349 | * Uses the Triangular Numbers method. 350 | * @param NumberOfElements Amount of elements 351 | * @return Number of element pairs 352 | */ 353 | UFUNCTION(BlueprintCallable, Category = "Jawadato|NativeFunctionLibrary|Statistics", Meta = (Keywords = "CalculateNumberOfPairs")) 354 | static int32 CalculateNumberOfPairs(int32 NumberOfElements); 355 | 356 | 357 | //MARK: CalculateLikelihood 358 | /** 359 | * Given the probability of an individual occurrence, returns the likelihood of said occurrence if repeated n times with the same probability. 360 | * Return a 0 to 1 percentage value. 361 | * @param Probability Probability of an individual occurrence 362 | * @param RepeatCount Likelihood of occurrence after trying this many times 363 | * @return Likelihood 364 | */ 365 | UFUNCTION(BlueprintCallable, Category = "Jawadato|NativeFunctionLibrary|Statistics", Meta = (Keywords = "CalculateLikelihood")) 366 | static float CalculateLikelihood(float Probability, int32 RepeatCount); 367 | 368 | 369 | //MARK: FlushInputs 370 | /** 371 | * Flushes all accumulated inputs. 372 | * @param PlayerController Player Controller which needs to be flushed 373 | */ 374 | UFUNCTION(BlueprintCallable, Category = "Jawadato|NativeFunctionLibrary|Input", Meta = (Keywords = "FlushInputs")) 375 | static void FlushInputs(APlayerController* PlayerController); 376 | 377 | 378 | //MARK: GetInputHeldDuration 379 | /** 380 | * Queries how long a particular input key has been held down for. 381 | * @param PlayerController Player Controller which to query against 382 | * @param Key Key to query 383 | * @return Duration in seconds of how long the Key has been held for 384 | */ 385 | UFUNCTION(BlueprintPure, Category = "Jawadato|NativeFunctionLibrary|Input", Meta = (Keywords = "GetInputHeldDuration")) 386 | static float GetInputHeldDuration(APlayerController* PlayerController, FKey Key); 387 | 388 | 389 | //MARK: GetHitResultAtScreenPosition 390 | /** 391 | * Does a collision query at the provided position on the screen. 392 | * @param PlayerController Player Controller to use 393 | * @param ScreenPosition Screen position to trace at 394 | * @param TraceChannel Trace collision channel to use 395 | * @param bTraceComplex Should trace complex collision 396 | * @param HitResult Result of trace 397 | * @return True or false depending on hit 398 | */ 399 | UFUNCTION(BlueprintPure, Category = "Jawadato|NativeFunctionLibrary|Player", Meta = (Keywords = "GetHitResultAtScreenPosition")) 400 | static bool GetHitResultAtScreenPosition(APlayerController* PlayerController, const FVector2D ScreenPosition, const ETraceTypeQuery TraceChannel, bool bTraceComplex, FHitResult& HitResult); 401 | 402 | 403 | //MARK: ClientFadeCamera 404 | /** 405 | * Smoothly interpolates the camera to the provided Linear Color over a certain duration. 406 | * @param PlayerController Player Controller to use 407 | * @param bFadeAudio Should also fade audio 408 | * @param bHoldWhenFinished Should retain fade color once alpha reaches stop value 409 | * @param FadeColor Linear Color structure used for the fade 410 | * @param FadeAlphaStart At alpha which to start the fade at 411 | * @param FadeAlphaStop Alpha towards the fade interpolates to 412 | * @param FadeDuration The interpolation duration in seconds 413 | */ 414 | UFUNCTION(BlueprintCallable, Category = "Jawadato|NativeFunctionLibrary|Player", Meta = (Keywords = "ClientFadeCamera", AdvancedDisplay = "2")) 415 | static void ClientFadeCamera(APlayerController* PlayerController, bool bFadeAudio, bool bHoldWhenFinished, FLinearColor FadeColor = FLinearColor(0.0, 0.66, 1.0), float FadeAlphaStart = 0.f, float FadeAlphaStop = 1.f, float FadeDuration = 1.f); 416 | 417 | 418 | //MARK: LocationOnScreen 419 | /** 420 | * Determines if provided location Vector is currently on screen relative to player camera. 421 | * @param PlayerController Player Controller which to query against 422 | * @param Location Location to query 423 | * @return True or false based on query result 424 | */ 425 | UFUNCTION(BlueprintPure, Category = "Jawadato|NativeFunctionLibrary|Player", Meta=(Keywords = "LocationOnScreen")) 426 | static bool LocationOnScreen(APlayerController* PlayerController, FVector Location); 427 | }; --------------------------------------------------------------------------------