Announcement

Collapse
No announcement yet.

(39) Rama's Extra Blueprint Nodes for You as a Plugin, No C++ Required!

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

    Rama's Suite of Powerful UMG Nodes

    Here are the 3 core BP nodes that I've been using to make all of my complicated interacting UMG menus, including an in-game file browser and a menu that allows you to change the materials on any skeletal mesh, while in-game!

    These nodes are available to you now!

    ~~~

    Get All Widgets of Class

    Allows you to not have to store references everywhere to your widgets, making it easy to interact with the Player Controller and My Character blueprints

    Also makes it easy to remove a loading screen after a level transition, without storing refs in Game Instance class

    ~~~

    Remove All Widgets Of Class

    You can find and remove any widget any time this way, no matter where you are in BP! (here I am in the Level BP)

    Rama Tip:
    If you make a general superclass for all your widgets (Reparent to a blank UserWidget of your own making), you can clear your entire UI system from the viewport with a single call to RemoveAllWidgetsOfClass, supplying the class that is your super class for all your user widgets!

    So lets say you have 3 user widgets that you made, make a 4th that is blank, reparent your existing 3 to your new empty 4th widget ("WidgetMaster" for example).

    Now you can just call RemoveAllWidgetsOfClass on your new 4th widget, WidgetMaster, and all 3 of your existing widgets will be removed automatically from the viewport!

    ~~~

    Is Widget Of Class In Viewport

    Take action based on the dynamic lookup of whether a certain widget is currently visible!

    No need to store refs or bools anywhere, just do a dynamic look up that is lightning fast!



    Rama

    Click image for larger version

Name:	UMGRamaNodes.jpg
Views:	5
Size:	162.4 KB
ID:	1062104
    100+ UE4 C++ Tutorials on the UE4 Code Wiki, including UE4 Multi-Threading!

    UE4 Marketplace: Melee Weapon Plugin & Compressed Binary Save System Plugin | Rama's C++ AI Jumping Videos | Vertex Snap Editor Plugin

    Visit www.ue4code.com to see lots of videos about my C++ Creations! ♥ Rama

    Comment


      BP Node to Get Your Computer's IP Address!

      Dear Community,

      I've finally succeeded at implementing a node that many have been trying to implement since the Beta!

      This is a BP node that gets the IP address of your computer!

      My node relies on http://api.ipify.org, a free and easy way to get your current IP address.

      Because this node involves an HTTP request I can't make it a static library node, so I instead made a VictoryPC class that contains only this functionality.

      You can easily re-parent your current player controller blueprint to use my plugin VictoryPC class!

      File->Reparent

      and if you are not using a PC already, make sure to go to World Settings and use my VictoryPC as your player controller!

      As long as my Victory BP Library is an active plugin for you, then this VictoryPC class will show up!

      Download:
      https://wiki.unrealengine.com/File:VictoryPlugin.zip

      ~~~

      Celebration!

      Yay!

      Now we can all get the IP address of the local computer for use with multiplayer games or webserver activities!

      Enjoy!

      Rama

      ~~~

      Pic

      Here's the setup you should create in your Blueprinted version of my VictoryPC!

      Click image for larger version

Name:	IPGetMyIP.jpg
Views:	11
Size:	177.0 KB
ID:	1062172

      ~~~

      C++ Source Code For You

      Here is the C++ source code I wrote just earlier today!

      Code:
      bool AVictoryPC::VictoryPC_GetMyIP_SendRequest()
      {
      	FHttpModule* Http = &FHttpModule::Get();
      	
      	if(!Http)
      	{
      		return false;
      	}
      	 
      	if(!Http->IsHttpEnabled()) 
      	{
      		return false;
      	} 
      	//~~~~~~~~~~~~~~~~~~~
      	
      	FString TargetHost = "http://api.ipify.org";
      	TSharedRef < IHttpRequest > Request = Http->CreateRequest(); 
      	Request->SetVerb("GET");
      	Request->SetURL(TargetHost);
      	Request->SetHeader("User-Agent", "VictoryBPLibrary/1.0");
      	Request->SetHeader("Content-Type" ,"text/html");
       
      	Request->OnProcessRequestComplete().BindUObject(this, &AVictoryPC::HTTPOnResponseReceived);
      	if (!Request->ProcessRequest())
      	{
      		return false;
      	}
      	  
      	return true;
      }
      	
      void AVictoryPC::HTTPOnResponseReceived(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful)
      {
      	this->VictoryPC_GetMyIP_DataReceived(Response->GetContentAsString());
      }


      Rama
      100+ UE4 C++ Tutorials on the UE4 Code Wiki, including UE4 Multi-Threading!

      UE4 Marketplace: Melee Weapon Plugin & Compressed Binary Save System Plugin | Rama's C++ AI Jumping Videos | Vertex Snap Editor Plugin

      Visit www.ue4code.com to see lots of videos about my C++ Creations! ♥ Rama

      Comment


        Video Guide to Installing Victory Plugin

        By Sahkan


        Here's a guide to installing my Victory Plugin, thanks for making it Sahkan!

        100+ UE4 C++ Tutorials on the UE4 Code Wiki, including UE4 Multi-Threading!

        UE4 Marketplace: Melee Weapon Plugin & Compressed Binary Save System Plugin | Rama's C++ AI Jumping Videos | Vertex Snap Editor Plugin

        Visit www.ue4code.com to see lots of videos about my C++ Creations! ♥ Rama

        Comment


          Code for you!

          Let me know if you want an actual copy.
          (note: all of my code should be within BeginRandom and EndRandom comments for ctrl-f ability)

          Also you are more than welcome to change anything you see fit. Code is 10000% free
          Originally posted by VictoryBPFunctionLibrary.H
          Code:
          /*    
              By Rama
          
          
          */
          #pragma once
          
          
          //~~~~~~~~~~~~ UMG ~~~~~~~~~~~~~~~
          #include "Runtime/UMG/Public/UMG.h"
          #include "Runtime/UMG/Public/UMGStyle.h"
          #include "Runtime/UMG/Public/Slate/SObjectWidget.h"
          #include "Runtime/UMG/Public/IUMGModule.h"
          #include "Runtime/UMG/Public/Blueprint/UserWidget.h"
          //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          
          
          //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          //                                    Includes for other's Nodes
          // Chrono and Random
          #include <chrono>
          #include <random>
          
          
          //Audio
          #include "Components/AudioComponent.h"
          #include "AudioDecompress.h"
          #include "AudioDevice.h"
          #include "ActiveSound.h"
          #include "Audio.h"
          #include "Developer/TargetPlatform/Public/Interfaces/IAudioFormat.h"
          #include "VorbisAudioInfo.h"
               
          //Texture2D
          //#include "Engine/Texture2D.h"
          #include "DDSLoader.h"
          //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          
          
          #include "VictoryBPFunctionLibrary.generated.h"
          
          
          // BP Library for You
          //
          // Written by Rama
          
          
          //note about UBlueprintFunctionLibrary
          // This class is a base class for any function libraries exposed to blueprints.
          // Methods in subclasses are expected to be static, and no methods should be added to the base class.
          
          
          
          
          USTRUCT(BlueprintType)
          struct FVictoryInput
          {
              GENERATED_USTRUCT_BODY()
          
          
              UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Input Song")
              FString ActionName;
              
              UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Input Song")
              FKey Key;
          
          
              UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Input Song")
              FString KeyAsString;
              
              UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Input Song")
              uint32 bShift:1;
          
          
              UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Input Song")
              uint32 bCtrl:1;
          
          
              UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Input Song")
              uint32 bAlt:1;
          
          
              UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Input Song")
              uint32 bCmd:1;
              
                 
              FVictoryInput(){}
              FVictoryInput(const FString InActionName, const FKey InKey, const bool bInShift, const bool bInCtrl, const bool bInAlt, const bool bInCmd)
                  : Key(InKey)
                  , KeyAsString(Key.GetDisplayName().ToString())
                  , bShift(bInShift)
                  , bCtrl(bInCtrl)
                  , bAlt(bInAlt)
                  , bCmd(bInCmd)
              { 
                  ActionName = InActionName;
              }
              
              FVictoryInput(const FInputActionKeyMapping& Action)
                  : Key(Action.Key)
                  , KeyAsString(Action.Key.GetDisplayName().ToString())
                  , bShift(Action.bShift)
                  , bCtrl(Action.bCtrl)
                  , bAlt(Action.bAlt)
                  , bCmd(Action.bCmd)
              {  
                  ActionName = Action.ActionName.ToString();
              }
          }; 
           
          UENUM(BlueprintType)
          namespace EJoyGraphicsFullScreen
          {
              //256 entries max
              enum Type
              {
                  FullScreen                                UMETA(DisplayName="Regular Full Screen"),
                  WindowedFullScreen                    UMETA(DisplayName="Windowed Full Screen High Quality"),
                  WindowedFullScreenPerformance        UMETA(DisplayName="Windowed Full Screen (Default)"),
                  //~~~
                  
                  //256th entry
                  EJoyGraphicsFullScreen_Max        UMETA(Hidden),
              };
          }
          
          
          
          
          UCLASS()
          class VICTORYBPLIBRARY_API UVictoryBPFunctionLibrary : public UBlueprintFunctionLibrary
          {
              GENERATED_UCLASS_BODY()
          
          
                  //~~~~ Key Re Binding ! ~~~~
          
          
                  UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Key Rebinding")
                  static FVictoryInput VictoryGetVictoryInput(const FKeyEvent& KeyEvent);
          
          
          
          
              static FORCEINLINE void UpdateActionMapping(FInputActionKeyMapping& Destination, const FVictoryInput& VictoryInputBind)
              {
                  Destination.Key = VictoryInputBind.Key;
                  Destination.bShift = VictoryInputBind.bShift;
                  Destination.bCtrl = VictoryInputBind.bCtrl;
                  Destination.bAlt = VictoryInputBind.bAlt;
                  Destination.bCmd = VictoryInputBind.bCmd;
              }
          
          
              UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Key Rebinding")
                  static void VictoryGetAllKeyBindings(TArray<FVictoryInput>& Bindings);
          
          
              /** You can leave the AsString field blank :) Returns false if the key could not be found as an existing mapping!  Enjoy! <3  Rama */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Key Rebinding")
                  static bool VictoryReBindKey(FVictoryInput Action);
          
          
              /*
                  To do = axis key bindings, check out same place where  FInputActionKeyMapping is defined
                  */
          
          
              //~~~~~~~~~~~~~~~~~~~~
          
          
              /** Change volume of Sound class of your choosing, sets the volume instantly! Returns false if the sound class was not found and volume was not set. */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Sound")
                  static bool VictorySoundVolumeChange(USoundClass* SoundClassObject, float NewVolume);
          
          
              /** Get Current Sound Volume! Returns -1 if sound class was not found*/
              UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Sound")
                  static float VictoryGetSoundVolume(USoundClass* SoundClassObject);
          
          
              //~~~~~~~~~~~~~~~~~~~~
          
          
          
          
          
          
          
          
          
          
          
          
              /** Get Custom Config Var! These are stored in Saved/Config/Windows/Game.ini */
              UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Custom Config Vars!")
                  static bool VictoryGetCustomConfigVar_Bool(FString SectionName, FString VariableName);
          
          
              /** Get Custom Config Var! These are stored in Saved/Config/Windows/Game.ini */
              UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Custom Config Vars!")
                  static int32 VictoryGetCustomConfigVar_Int(FString SectionName, FString VariableName);
          
          
              /** Get Custom Config Var! These are stored in Saved/Config/Windows/Game.ini */
              UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Custom Config Vars!")
                  static float VictoryGetCustomConfigVar_Float(FString SectionName, FString VariableName);
          
          
              /** Get Custom Config Var! These are stored in Saved/Config/Windows/Game.ini */
              UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Custom Config Vars!")
                  static FVector VictoryGetCustomConfigVar_Vector(FString SectionName, FString VariableName);
          
          
              /** Get Custom Config Var! These are stored in Saved/Config/Windows/Game.ini */
              UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Custom Config Vars!")
                  static FRotator VictoryGetCustomConfigVar_Rotator(FString SectionName, FString VariableName);
          
          
              /** Get Custom Config Var! These are stored in Saved/Config/Windows/Game.ini */
              UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Custom Config Vars!")
                  static FLinearColor VictoryGetCustomConfigVar_Color(FString SectionName, FString VariableName);
          
          
              /** Get Custom Config Var! These are stored in Saved/Config/Windows/Game.ini */
              UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Custom Config Vars!")
                  static FString VictoryGetCustomConfigVar_String(FString SectionName, FString VariableName);
          
          
              //~~~~~~~~~~~~~~~~~~~~
          
          
              /** Set Custom Config Var! These are stored in Saved/Config/Windows/Game.ini */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Custom Config Vars!")
                  static void VictorySetCustomConfigVar_Bool(FString SectionName, FString VariableName, bool Value);
          
          
              /** Set Custom Config Var! These are stored in Saved/Config/Windows/Game.ini */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Custom Config Vars!")
                  static void VictorySetCustomConfigVar_Int(FString SectionName, FString VariableName, int32 Value);
          
          
              /** Set Custom Config Var! These are stored in Saved/Config/Windows/Game.ini */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Custom Config Vars!")
                  static void VictorySetCustomConfigVar_Float(FString SectionName, FString VariableName, float Value);
          
          
              /** Set Custom Config Var! These are stored in Saved/Config/Windows/Game.ini */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Custom Config Vars!")
                  static void VictorySetCustomConfigVar_Vector(FString SectionName, FString VariableName, FVector Value);
          
          
              /** Set Custom Config Var! These are stored in Saved/Config/Windows/Game.ini */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Custom Config Vars!")
                  static void VictorySetCustomConfigVar_Rotator(FString SectionName, FString VariableName, FRotator Value);
          
          
              /** Set Custom Config Var! These are stored in Saved/Config/Windows/Game.ini */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Custom Config Vars!")
                  static void VictorySetCustomConfigVar_Color(FString SectionName, FString VariableName, FLinearColor Value);
          
          
          
          
              /** Set Custom Config Var! These are stored in Saved/Config/Windows/Game.ini */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Custom Config Vars!")
                  static void VictorySetCustomConfigVar_String(FString SectionName, FString VariableName, FString Value);
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
              /** The FName that is expected is the exact same format as when you right click on asset -> Copy Reference! You can directly paste copied references into this node! IsValid lets you know if the path was correct or not and I was able to load the object. MAKE SURE TO SAVE THE RETURNED OBJECT AS A VARIABLE. Otherwise your shiny new asset will get garbage collected. I recommend you cast the return value to the appropriate object and then promote it to a variable :)  -Rama */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
                  static UObject* LoadObjectFromAssetPath(TSubclassOf<UObject> ObjectClass, FName Path, bool& IsValid);
          
          
              /** Uses the same format as I use for LoadObjectFromAssetPath! Use this node to get the asset path of objects in the world! -Rama */
              UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary")
                  static FName GetObjectPath(UObject* Obj);
          
          
          
          
              /** Find all widgets of a certain class! Top level only means only widgets that are directly added to the viewport will be found */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|UMG", meta = (HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"))
                  static void GetAllWidgetsOfClass(UObject* WorldContextObject, TSubclassOf<UUserWidget> WidgetClass, TArray<UUserWidget*>& FoundWidgets, bool TopLevelOnly = true);
          
          
              /** Remove all widgets of a certain class from viewport! */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|UMG", meta = (HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"))
                  static void RemoveAllWidgetsOfClass(UObject* WorldContextObject, TSubclassOf<UUserWidget> WidgetClass);
          
          
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|UMG", meta = (HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"))
                  static bool IsWidgetOfClassInViewport(UObject* WorldContextObject, TSubclassOf<UUserWidget> WidgetClass);
          
          
          
          
              /** Retrieves the unique net ID for the local player as a number! The number itself will vary based on what Online Subsystem is being used, but you are guaranteed that this number is unique per player! */
              UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary")
                  static int32 GetPlayerUniqueNetID();
          
          
              /** Call this periodically in a huge loop you are intentionally using to reset the BP runaway loop system. Caution, if you have an infinite loop this will permanently hang your system until you turn your computer off. Use very very carefully! When constructing a new loop and you are not sure if it is totally stable, do NOT use this node! Always test new loops normally to ensure you dont truly have a runaway loop that would hang your computer forever. */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
                  static void Loops_ResetBPRunawayCounter();
          
          
              /** Set the Max Frame Rate. Min value is 10. */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Graphics Settings")
                  static void GraphicsSettings__SetFrameRateCap(float NewValue);
          
          
              /** Only hardware dependent, no smoothing */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Graphics Settings")
                  static void GraphicsSettings__SetFrameRateToBeUnbound();
          
          
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
                  static FVector2D ProjectWorldToScreenPosition(const FVector& WorldLocation);
          
          
              /** Make sure to save off the return value as a global variable in one of your BPs or else it will get garbage collected! */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary", meta = (HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"))
                  static UObject* CreateObject(UObject* WorldContextObject, UClass* TheObjectClass, FName Name);
          
          
              /** Make sure to save off the return value as a global variable in one of your BPs or else it will get garbage collected! */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary", meta = (HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"))
                  static UPrimitiveComponent* CreatePrimitiveComponent(UObject* WorldContextObject, TSubclassOf<UPrimitiveComponent> CompClass, FName Name, FVector Location, FRotator Rotation);
          
          
          
          
          
          
              /** Spawn an Actor and choose which level you want them to spawn into! */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary", meta = (HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"))
                  static AActor* SpawnActorIntoLevel(UObject* WorldContextObject, TSubclassOf<AActor> ActorClass, FName Level = NAME_None, FVector Location = FVector::ZeroVector, FRotator Rotation = FRotator::ZeroRotator, bool SpawnEvenIfColliding = true);
          
          
              /** Get the names of all currently loaded and visible levels! */
              UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary", meta = (HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"))
                  static void GetNamesOfLoadedLevels(UObject* WorldContextObject, TArray<FString>& NamesOfLoadedLevels);
          
          
          
          
          
          
          
          
              /** Obtain the scaled,rotated, and translated vertex positions for any static mesh! Returns false if operation could not occur because the comp or static mesh asset was invalid. <3 Rama */
              UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary")
                  static bool GetStaticMeshVertexLocations(UStaticMeshComponent* Comp, TArray<FVector>& VertexPositions);
          
          
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
                  static void AddToActorRotation(AActor* TheActor, FRotator AddRot);
          
          
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary", meta = (HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"))
                  static void DrawCircle(
                  UObject* WorldContextObject,
                  FVector Center,
                  float Radius,
                  int32 NumPoints = 32,
                  float Thickness = 7,
                  FLinearColor LineColor = FLinearColor::Red,
                  FVector YAxis = FVector(0, 1, 0),
                  FVector ZAxis = FVector(0, 0, 1),
                  float Duration = 0,
                  bool PersistentLines = false
                  );
          
          
          
          
          
          
              /** Implementation of a Selection Marquee / Selection Box as a BP Node. AnchorPoint is the first clicked point, which user then drags from to make the box. Class filter is optional way to narrow the scope of actors that can be selected by the selection box! -Rama*/
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary", meta = (HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"))
                  static void Selection_SelectionBox(UObject* WorldContextObject, TArray<AActor*>& SelectedActors, FVector2D AnchorPoint, FVector2D DraggedPoint, TSubclassOf<AActor> ClassFilter);
          
          
          
          
              /** Get the Controller ID for a supplied Player Controller <3 Rama. Returns false if operation could not occur.  */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
                  static bool PlayerController_GetControllerID(APlayerController* ThePC, int32& ControllerID);
          
          
              /** Get the Unique PlayerID from the PlayerState for a supplied Player Controller <3 Rama. Returns false if operation could not occur. */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
                  static bool PlayerState_GetPlayerID(APlayerController* ThePC, int32& PlayerID);
          
          
          
          
              /** Launches the specified URL in the OS default web browser :) <3 Rama */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
                  static void Open_URL_In_Web_Browser(FString TheURL);
          
          
          
          
          
          
              /** Returns which platform the game code is running in.*/
              UFUNCTION(BlueprintCallable, BlueprintPure, Category = "VictoryBPLibrary")
                  static void OperatingSystem__GetCurrentPlatform(
                  bool& Windows_,
                  bool& Mac,
                  bool& Linux,
                  bool& iOS,
                  bool& Android,
                  bool& PS4,
                  bool& XBoxOne,
                  bool& HTML5,
                  bool& WinRT_Arm,
                  bool& WinRT
                  );
          
          
              //~~~
          
          
              /** Retrieves the OS system Date and Time as a string at the instant this BP node runs. Use my other RealWorldTime node to get the time passed since the return value of this node! You can use this to record milliseconds/seconds/minutes/hours between events in game logic! */
              UFUNCTION(BlueprintCallable, BlueprintPure, Category = "VictoryBPLibrary")
                  static FString RealWorldTime__GetCurrentOSTime(
                  int32& MilliSeconds,
                  int32& Seconds,
                  int32& Minutes,
                  int32& Hours12,
                  int32& Hours24,
                  int32& Day,
                  int32& Month,
                  int32& Year
                  );
          
          
              /** Get the amount of seconds/minutes/hours since the the supplied DateTime string! You can use this to record milliseconds/seconds/minutes/hours between events in game logic! */
              UFUNCTION(BlueprintCallable, BlueprintPure, Category = "VictoryBPLibrary")
                  static void RealWorldTime__GetTimePassedSincePreviousTime(
                  const FString& PreviousTime,
                  float& Milliseconds,
                  float& Seconds,
                  float& Minutes,
                  float& Hours
                  );
          
          
              /** Get the difference between two recorded times! You can use this to record milliseconds/seconds/minutes/hours between events in game logic! */
              UFUNCTION(BlueprintCallable, BlueprintPure, Category = "VictoryBPLibrary")
                  static void RealWorldTime__GetDifferenceBetweenTimes(
                  const FString& PreviousTime1,
                  const FString& PreviousTime2,
                  float& Milliseconds,
                  float& Seconds,
                  float& Minutes,
                  float& Hours
                  );
          
          
              //~~~
          
          
              /** Loads a text file from hard disk and parses it into a String array, where each entry in the string array is 1 line from the text file. Option to exclude lines that are only whitespace characters or '\n'. Returns the size of the final String Array that was created. Returns false if the file could be loaded from hard disk. */
              UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary")
                  static bool LoadStringArrayFromFile(TArray<FString>& StringArray, int32& ArraySize, FString FullFilePath = "Enter Full File Path", bool ExcludeEmptyLines = false);
          
          
              //~~~
          
          
              /** Max of all array entries. Returns -1 if the supplied array is empty. Returns the index of the max value as well as the value itself. */
              UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary")
                  static void MaxOfFloatArray(const TArray<float>& FloatArray, int32& IndexOfMaxValue, float& MaxValue);
          
          
              /** Max of all array entries. Returns -1 if the supplied array is empty. Returns the index of the max value as well as the value itself. */
              UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary")
                  static void MaxOfIntArray(const TArray<int32>& IntArray, int32& IndexOfMaxValue, int32& MaxValue);
          
          
              /** Min of all array entries. Returns -1 if the supplied array is empty. Returns the index of the min value as well as the value itself. */
              UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary")
                  static void MinOfFloatArray(const TArray<float>& FloatArray, int32& IndexOfMinValue, float& MinValue);
          
          
              /** Min of all array entries. Returns -1 if the supplied array is empty. Returns the index of the min value as well as the value itself. */
              UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary")
                  static void MinOfIntArray(const TArray<int32>& IntArray, int32& IndexOfMinValue, int32& MinValue);
          
          
              //~~~
          
          
              /** Set Max Move Speed. Supply the Character whose Character Movement to change! Returns false if operation could not occur due to invalid Character or MovementComponent could not be obtained.*/
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary", meta = (DefaultToSelf = "TheCharacter"))
                  static bool CharacterMovement__SetMaxMoveSpeed(ACharacter* TheCharacter, float NewMaxMoveSpeed);
          
          
              //~~~
          
          
              /** Converts a float to a rounded Integer, examples: 1.4 becomes 1,   1.6 becomes 2 */
              UFUNCTION(BlueprintCallable, BlueprintPure, Category = "VictoryBPLibrary")
                  static int32 Conversion__FloatToRoundedInteger(float IN_Float);
          
          
              /** Combines two strings together! The Separator and the Labels are optional*/
              UFUNCTION(BlueprintCallable, BlueprintPure, Category = "VictoryBPLibrary")
                  static FString String__CombineStrings(FString StringFirst, FString StringSecond, FString Separator = "", FString StringFirstLabel = "", FString StringSecondLabel = "");
          
          
          
          
              /** Returns three arrays containing all of the resolutions and refresh rates for the current computer's current display adapter. You can loop over just 1 of the arrays and use the current index for the other two arrays, as all 3 arrays will always have the same length. Returns false if operation could not occur. */
              UFUNCTION(BlueprintCallable, BlueprintPure, Category = "VictoryBPLibrary", meta = (Keywords = "screen resolutions display adapater"))
                  static bool OptionsMenu__GetDisplayAdapterScreenResolutions(TArray<int32>& Widths, TArray<int32>& Heights, TArray<int32>& RefreshRates, bool IncludeRefreshRates = false);
          
          
              /** Clones an actor by obtaining its class and creating a copy. Returns the created Actor. The cloned actor is set to have the rotation and location of the initial actor. You can optionally specify location / rotation offsets for the new clone from original actor. Use IsValid to know if the actor was able to be cloned. */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary", meta = (HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"))
                  static AStaticMeshActor* Clone__StaticMeshActor(UObject* WorldContextObject, bool&IsValid, AStaticMeshActor* ToClone, FVector LocationOffset = FVector(0, 0, 0), FRotator RotationOffset = FRotator(0, 0, 0));
          
          
          
          
              /** Teleport Actor To Actor. Moves an actor instantly to the position and rotation of another actor. Useful for player starts, notes, triggers, and any other destination actors who dont have collision. Returns false if the operation could not occur. */
              UFUNCTION(BlueprintCallable, BlueprintPure, Category = "VictoryBPLibrary")
                  static bool Actor__TeleportToActor(AActor* ActorToTeleport, AActor* DestinationActor);
          
          
              /** Is this game logic running in the Editor world? */
              UFUNCTION(BlueprintCallable, BlueprintPure, Category = "VictoryBPLibrary", meta = (HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"))
                  static bool WorldType__InEditorWorld(UObject* WorldContextObject);
          
          
              /** Is this game logic running in the PIE world? */
              UFUNCTION(BlueprintCallable, BlueprintPure, Category = "VictoryBPLibrary", meta = (HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"))
                  static bool WorldType__InPIEWorld(UObject* WorldContextObject);
          
          
              /** Is this game logic running in an actual independent game instance? */
              UFUNCTION(BlueprintCallable, BlueprintPure, Category = "VictoryBPLibrary", meta = (HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"))
                  static bool WorldType__InGameInstanceWorld(UObject* WorldContextObject);
          
          
              /** Cause a supplied Character (casted from Actor internally) to enter Ragdoll physics. A check will be done to see if the character has a physics asset. */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
                  static bool Physics__EnterRagDoll(AActor* TheCharacter);
          
          
              /** Cause a supplied Character (casted from Actor internally) to exit Ragdoll physics. HeightAboveRBMesh is how far above the RB Mesh the Actor Capsule should be moved to upon exiting. Pass in the InitLocation and InitRotation from InitializeVictoryRagdoll */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
                  static bool Physics__LeaveRagDoll(AActor* TheCharacter, float HeightAboveRBMesh = 64, const FVector& InitLocation = FVector(0, 0, 0), const FRotator& InitRotation = FRotator(0, 0, 0));
          
          
              /** Returns whether or not a supplied Character is in Ragdoll Physics. Cast from Actor done internally for your convenience. */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
                  static bool Physics__IsRagDoll(AActor* TheCharacter);
          
          
              /** Get the Ragdoll Position of the supplied actor, casted to Character internally. Returns false if operation could not occur. */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
                  static bool Physics__GetLocationofRagDoll(AActor* TheCharacter, FVector& RagdollLocation);
          
          
              /** Initialize Victory Ragdoll Mode, by Obtaining the Default Relative Rotation and Location for this Character's Mesh. The Output Location and Rotation must be saved for use with LeaveRagdoll. Returns false if operation could not occur */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
                  static bool Physics__InitializeVictoryRagDoll(AActor* TheCharacter, FVector&InitLocation, FRotator&InitRotation);
          
          
              /** Update the TheCharacter's Capsule Location and Camera to the Current Location of the Ragdoll. InterpSpeed is how fast the camera keeps up with the moving ragdoll! HeightOffset is the height above the ragdoll that the camera should stay. Returns false if operation could not occur or if Mesh was not in ragdoll */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
                  static bool Physics__UpdateCharacterCameraToRagdollLocation(AActor* TheCharacter, float HeightOffset = 128, float InterpSpeed = 3);
          
          
              /** Get Name as String*/
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
                  static FString Accessor__GetNameAsString(const UObject* TheObject);
          
          
              /** Get Socket Local Transform. Returns false if operation could not occur.*/
              //UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
              //static bool Accessor__GetSocketLocalTransform(const USkeletalMeshComponent* Mesh, FTransform& LocalTransform, FName SocketName=FName("SocketName"));
          
          
              /** Get Player Character's Player Controller. Requires: The Passed in Actor must be a character and it must be a player controlled character. IsValid will tell you if the return value is valid, make sure to do a Branch to confirm this! */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
                  static APlayerController* Accessor__GetPlayerController(AActor* TheCharacter, bool&IsValid);
          
          
              /** SET the Mouse Position! Returns false if the operation could not occur */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
                  static bool Viewport__SetMousePosition(const APlayerController* ThePC, const float& PosX, const float& PosY);
          
          
              /** Get the Cursor Position within the Player's Viewport. This will return a result consistent with SET Mouse Position Returns false if the operation could not occur */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
                  static bool Viewport__GetMousePosition(const APlayerController* ThePC, float& PosX, float& PosY);
          
          
              /** Get the coordinates of the center of the player's screen / viewport. Returns false if the operation could not occur */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
                  static bool Viewport__GetCenterOfViewport(const APlayerController* ThePC, float& PosX, float& PosY);
          
          
          
          
          
          
              /** Convert Rotator to Vector */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
                  static FRotator Conversions__VectorToRotator(const FVector& TheVector);
          
          
              /** Convert Vector to Rotator*/
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
                  static FVector Conversions__RotatorToVector(const FRotator& TheRotator);
          
          
              /** Input Actor is expected to be a ACharacter, conversion done internally for your convenience */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
                  static FRotator Character__GetControllerRotation(AActor * TheCharacter);
          
          
              /** Draw 3D Line of Chosen Thickness From Socket on Character's Mesh to Destination, conversion of AActor to ACharacter done internally for your convenience. Duration is in Seconds */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
                  static void Draw__Thick3DLineFromCharacterSocket(AActor* TheCharacter, const FVector& EndPoint, FName Socket = FName("SocketName"), FLinearColor LineColor = FLinearColor(1, 0, 0, 1), float Thickness = 7, float Duration = -1.f);
              /** Draw 3D Line of Chosen Thickness From Mesh Socket to Destination. Duration is in Seconds */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
                  static void Draw__Thick3DLineFromSocket(USkeletalMeshComponent* Mesh, const FVector& EndPoint, FName Socket = FName("SocketName"), FLinearColor LineColor = FLinearColor(0, 1, 0, 1), float Thickness = 7, float Duration = -1.f);
              /** Draw 3D Line of Chosen Thickness Between Two Actors. Duration is in Seconds */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
                  static void Draw__Thick3DLineBetweenActors(AActor* StartActor, AActor* EndActor, FLinearColor LineColor = FLinearColor(0, 0, 1, 1), float Thickness = 7, float Duration = -1.f);
          
          
              /** AnimBPOwner - Must be a Character, Conversion Internally For Convenience.\n\nRetrieves the Aim Offsets Pitch & Yaw Based On the Rotation of the Controller of The Character Owning The Anim Instance.\n\nThe Pitch and Yaw are meant to be used with a Blend Space going from -90,-90 to 90,90.\n   Returns true if function filled the pitch and yaw vars successfully */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
                  static bool Animation__GetAimOffsets(AActor* AnimBPOwner, float& Pitch, float& Yaw);
          
          
              /** AnimBPOwner - Must be a Character, Conversion Internally For Convenience.\n\nRetrieves the Aim Offsets Pitch & Yaw for the AnimBPOwner Based On the supplied Rotation.\n\nThe Pitch and Yaw are meant to be used with a Blend Space going from -90,-90 to 90,90.\n    Returns true if function filled the pitch and yaw vars successfully */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
                  static bool Animation__GetAimOffsetsFromRotation(AActor * AnimBPOwner, const FRotator & TheRotation, float & Pitch, float & Yaw);
          
          
              /** Saves text to filename of your choosing, make sure include whichever file extension you want in the filename, ex: SelfNotes.txt . Make sure to include the entire file path in the save directory, ex: C:\MyGameDir\BPSavedTextFiles */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
                  static bool FileIO__SaveStringTextToFile(FString SaveDirectory, FString JoyfulFileName, FString SaveText, bool AllowOverWriting = false);
          
          
              /** Obtain an Array of Actors Rendered Recently. You can specifiy what qualifies as "Recent" in seconds. */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
                  static void Visibility__GetRenderedActors(TArray<AActor*>& CurrentlyRenderedActors, float MinRecentTime = 0.01);
          
          
              /** Obtain an Array of Actors NOT Rendered Recently! You can specifiy what qualifies as "Recent" in seconds. */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
                  static void Visibility__GetNotRenderedActors(TArray<AActor*>& CurrentlyNotRenderedActors, float MinRecentTime = 0.01);
          
          
              /** Is the Current Game Window the Foreground window in the OS, or in the Editor? This will be accurate in standalone running of the game as well as in the editor PIE */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
                  static bool ClientWindow__GameWindowIsForeGroundInOS();
          
          
              /** Freeze Game Render, Does Not Stop Game Logic, Just Rendering. This is not like Pausing. Mainly useful for freezing render when window is not in the foreground */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
                  static void Rendering__FreezeGameRendering();
          
          
              /** Unfreeze Game Render. This is not an unpause function, it's just for actual screen rendering */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
                  static void Rendering__UnFreezeGameRendering();
          
          
              /** Compare Source Vector against Array of Vectors. Returns: Returns the Closest Vector to Source and what that closest Distance is, or -1 if there was an error such as array being empty. Ignores: Ignores Source if source is in the array */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
                  static float Calcs__ClosestPointToSourcePoint(const FVector & Source, const TArray<FVector>& OtherPoints, FVector& ClosestPoint);
          
          
              /** Takes in an actor (for convenience) and tries to cast it to Character and return an array of Vectors of all of the current bone locations of the character's Mesh. Locations are in World Space. Returns: false if the operation could not occur. Requires: Character Mesh Component must be valid */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
                  static bool Data__GetCharacterBoneLocations(AActor * TheCharacter, TArray<FVector>& BoneLocations);
          
          
              /** Retrieves the "Mesh" component of a Character. IsValid lets you know if the data is valid, make sure to check if it is! Requires: the passed in Actor must be a Character */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
                  static USkeletalMeshComponent* Accessor__GetCharacterSkeletalMesh(AActor* TheCharacter, bool& IsValid);
          
          
              /** Does Not Do A Trace, But Obtains the Start and End for doing a Trace:\n\nTakes in an actor (for convenience) and tries to cast it to Character. Takes in a socket name to find on the Character's Mesh component, the socket location will be the start of the trace.\n\nAlso takes in the Angle / Rotator and the length of the trace you want to do. Option to draw the trace with variable thickness as it occurs.\n\nReturns what the Trace Start and End should be so you can plug these into any existing trace node you want.\n\nRequires: Character Mesh Component must be valid. Returns False if trace could not be done */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Traces")
                  static bool TraceData__GetTraceDataFromCharacterSocket(FVector& TraceStart, FVector& TraceEnd, AActor * TheCharacter, const FRotator& TraceRotation, float TraceLength = 10240, FName Socket = "SocketName", bool DrawTraceData = true, FLinearColor TraceDataColor = FLinearColor(1, 0, 0, 1), float TraceDataThickness = 7);
          
          
              /** Does Not Do A Trace, But Obtains the Start and End for doing a Trace:\n\nTakes in a Skeletal Mesh Component and a socket name to trace from. Also takes in the Angle / Rotator and the length of the trace you want to do.\n\nOption to draw the trace as a variable thickness line\n\nReturns what the Trace Start and End should be so you can plug these into any existing trace node you want.\n\n Requires: Mesh must be valid. Returns False if trace could not be done */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Traces")
                  static bool TraceData__GetTraceDataFromSkeletalMeshSocket(FVector& TraceStart, FVector& TraceEnd, USkeletalMeshComponent* Mesh, const FRotator& TraceRotation, float TraceLength = 10240, FName Socket = "SocketName", bool DrawTraceData = true, FLinearColor TraceDataColor = FLinearColor(1, 0, 0, 1), float TraceDataThickness = 7);
          
          
              /** Does a simple line trace given Trace Start and End, and if a Character is hit by the trace, then a component trace is performed on that character's mesh. Trace Owner is ignored when doing the trace.\n\nReturns the Character that was hit, as an Actor, as well as the name of the bone that was closest to the impact point of the trace. Also returns the impact point itself as well as the impact normal.\n\nUsing component trace ensures accuracy for testing against bones and sockets.\n\nIsValid: Will be true only if the component trace also hit someting. But the Returned Actor will contain an actor if any actor at all was hit by the simple trace. */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Traces")
                  static AActor* Traces__CharacterMeshTrace___ClosestBone(AActor* TraceOwner, const FVector& TraceStart, const FVector& TraceEnd, FVector& OutImpactPoint, FVector& OutImpactNormal, FName& ClosestBoneName, FVector & ClosestBoneLocation, bool&IsValid);
          
          
              /** Does a simple line trace given Trace Start and End, and if a Character is hit by the trace, then a component trace is performed on that character's mesh. Returns the name of the socket that was closest to the impact point of the trace. Also returns the impact point itself as well as the impact normal. Also returns the Socket Location. Using component trace ensures accuracy for testing against bones and sockets.*/
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Traces")
                  static AActor* Traces__CharacterMeshTrace___ClosestSocket(const AActor * TraceOwner, const FVector& TraceStart, const FVector& TraceEnd, FVector& OutImpactPoint, FVector& OutImpactNormal, FName& ClosestSocketName, FVector & SocketLocation, bool&IsValid);
          
          
              /** Returns the float as a String with Precision, Precision 0 = no decimal value. Precison 1 = 1 decimal place. The re-precisioned result is rounded appropriately. */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
                  static void StringConversion__GetFloatAsStringWithPrecision(float TheFloat, FString & TheString, uint8 Precision = 2);
          
          
              /** Rotator out value is the degrees of difference between the player camera and the direction of player to light source. Returns false if the operation could not occur. */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
                  static bool LensFlare__GetLensFlareOffsets(APlayerController* PlayerController, AActor* LightSource, float& PitchOffset, float& YawOffset, float& RollOffset);
          
          
              //~~~~~~~~~~~~~
          
          
              /** Returns false if the operation could not occur. */
              //UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
              //static bool AnimatedVertex__GetAnimatedVertexLocations(USkeletalMeshComponent* Mesh, TArray<FVector>& Locations );
          
          
              /** Returns false if the operation could not occur. */
              //UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
              //static bool AnimatedVertex__GetAnimatedVertexLocationsAndNormals(USkeletalMeshComponent* Mesh, TArray<FVector>& Locations, TArray<FVector>& Normals );
          
          
              /** 0 never skip, 0.5 = 50% chance to skip, 1 = skip all. Returns false if the operation could not occur. */
              //UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary", meta=(HidePin="WorldContextObject", DefaultToSelf="WorldContextObject" ))
              //static bool AnimatedVertex__DrawAnimatedVertexLocations(UObject* WorldContextObject, USkeletalMeshComponent* Mesh, float ChanceToSkipAVertex=0.777, bool DrawNormals=false);
          
          
              //~~~~~~~~~~~~~
          
          
              /** Returns false if the operation could not occur. */
              //UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary", meta=(DefaultToSelf="TheCharacter"))
              //static bool AnimatedVertex__GetCharacterAnimatedVertexLocations(AActor* TheCharacter, TArray<FVector>& Locations );
          
          
              /** Returns false if the operation could not occur. */
              //UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary", meta=(DefaultToSelf="TheCharacter"))
              //static bool AnimatedVertex__GetCharacterAnimatedVertexLocationsAndNormals(AActor* TheCharacter, TArray<FVector>& Locations, TArray<FVector>& Normals );
          
          
              /** 0 never skip, 0.5 = 50% chance to skip, 1 = skip all.. Returns false if the operation could not occur. */
              //UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
              //static bool AnimatedVertex__DrawCharacterAnimatedVertexLocations(AActor* TheCharacter, float ChanceToSkipAVertex=0.777, bool DrawNormals=false);
          
          
              /** Retrieve Distance of given point to any Surface point on a Static Mesh Actor. Returns the distance as well as the exact closest point on the mesh surface to the given point. Returns -1 if an error occurred*/
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
                  static float DistanceToSurface__DistaceOfPointToMeshSurface(AStaticMeshActor* TheSMA, const FVector& TestPoint, FVector& ClosestSurfacePoint);
          
          
              /** Change the Mobility of a Static Mesh Component, can be used in Constructor Script or in Event Graph! Returns false if operation could not occur.*/
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
                  static bool Mobility__SetSceneCompMobility(USceneComponent* SceneComp, EComponentMobility::Type NewMobility);
          
          
          
          
          
          
              //~~~~~~~~~~~~~~~~~~~~~~~~~~~
              //~~~~~~~~~~~~~~~~~~~~~~~~~~~
              //~~~~~~~~~~~~~~~~~~~~~~~~~~~
              //              Graphics Settings Sample
          
          
              //~~~~~~~~~~~~~~~~~~
              //        FullScreen
              //~~~~~~~~~~~~~~~~~~
          
          
              /** Get Full Screen Type */
              UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Graphics Settings")
                  static TEnumAsByte<EJoyGraphicsFullScreen::Type> JoyGraphicsSettings__FullScreen_Get();
          
          
              /** Set Full Screen Type */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Graphics Settings")
                  static void JoyGraphicsSettings__FullScreen_Set(TEnumAsByte<EJoyGraphicsFullScreen::Type> NewSetting);
          
          
          
          
          
          
              //~~~~~~~~~~~~~~~~~~~~~~~~~~~
              //~~~~~~~~~~~~~~~~~~~~~~~~~~~
              //~~~~~~~~~~~~~~~~~~~~~~~~~~~
              //              CPP FUNCTION LIBRARY
          
          
              static FORCEINLINE void JoyCC(const FString& Str, const int32 Value)
              {
                  TObjectIterator<APlayerController> PC;
                  if (!PC) return;
                  //~~~~~~
          
          
                  PC->ConsoleCommand(Str + " " + FString::FromInt(Value));
              }
              static FORCEINLINE void JoyGraphics_FullScreen_SetFullScreenType(int32 Value)
              {
                  JoyCC("r.FullScreenMode", Value);
              }
              static FORCEINLINE int32 JoyGraphics_FullScreen_GetFullScreenType()
              {
                  static const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.FullScreenMode"));
                  return CVar->GetValueOnGameThread();
              }
              static FORCEINLINE void JoyGraphics_SetFullScreen_NonWindowed()
              {
                  /*"r.FullScreenMode"),
                      2,
                      TEXT("Defines how we do full screen when requested (e.g. command line option -fullscreen or in ini [SystemSettings] fullscreen=true)\n")
                      */
                  JoyCC("r.FullScreenMode", 0);
              }
              static FORCEINLINE void JoyGraphics_SetFullScreen_Windowed()
              {
                  //TEXT(" 2: windowed full screen, specified resolution (like 1 but no unintuitive performance cliff, can be blurry, default)\n")
                  JoyCC("r.FullScreenMode", 2);
              }
              static FORCEINLINE void JoyGraphics_SetFullScreen_WindowedHighestQuality()
              {
                  //TEXT(" 1: windowed full screen, desktop resolution (quick switch between applications and window mode, full quality)\n")
                  JoyCC("r.FullScreenMode", 1);
              }
          
          
          
          
          
          
              //Min and Max of Array
              static FORCEINLINE float Min(const TArray<float>& Values, int32* MinIndex = NULL)
              {
                  if (MinIndex)
                  {
                      *MinIndex = 0;
                  }
          
          
                  if (Values.Num() <= 0)
                  {
                      return -1;
                  }
          
          
                  float CurMin = Values[0];
                  for (const float EachValue : Values)
                  {
                      CurMin = FMath::Min(CurMin, EachValue);
                  }
          
          
                  if (MinIndex)
                  {
                      *MinIndex = Values.Find(CurMin);
                  }
                  return CurMin;
              }
              static FORCEINLINE float Max(const TArray<float>& Values, int32* MaxIndex = NULL)
              {
                  if (MaxIndex)
                  {
                      *MaxIndex = 0;
                  }
          
          
                  if (Values.Num() <= 0)
                  {
                      return -1;
                  }
          
          
                  float CurMax = Values[0];
                  for (const float EachValue : Values)
                  {
                      CurMax = FMath::Max(CurMax, EachValue);
                  }
          
          
                  if (MaxIndex)
                  {
                      *MaxIndex = Values.Find(CurMax);
                  }
                  return CurMax;
              }
          
          
              static FORCEINLINE int32 Min(const TArray<int32>& Values, int32* MinIndex = NULL)
              {
                  if (MinIndex)
                  {
                      *MinIndex = 0;
                  }
          
          
                  if (Values.Num() <= 0)
                  {
                      return -1;
                  }
          
          
                  int32 CurMin = Values[0];
                  for (const int32 EachValue : Values)
                  {
                      CurMin = FMath::Min(CurMin, EachValue);
                  }
          
          
                  if (MinIndex)
                  {
                      *MinIndex = Values.Find(CurMin);
                  }
                  return CurMin;
              }
              static FORCEINLINE int32 Max(const TArray<int32>& Values, int32* MaxIndex = NULL)
              {
                  if (MaxIndex)
                  {
                      *MaxIndex = 0;
                  }
          
          
                  if (Values.Num() <= 0)
                  {
                      return -1;
                  }
          
          
                  int32 CurMax = Values[0];
                  for (const int32 EachValue : Values)
                  {
                      CurMax = FMath::Max(CurMax, EachValue);
                  }
          
          
                  if (MaxIndex)
                  {
                      *MaxIndex = Values.Find(CurMax);
                  }
                  return CurMax;
              }
          
          
              
              
              
              
              
              
              
              
              
              
              
              
              
              
              
              
              
              
              
              
              
              
              //~~~~~~~~~~~~~~~~~~~~~~~~~~~
              //~~~~~~~~~~~~~~~~~~~~~~~~~~~
              //~~~~~~~~~~~~~~~~~~~~~~~~~~~
              //              Contributed by Others
              
              /**
              *
              * Contributed by: Mindfane
              *
              * Split a string into an array of substrings based on the given delimitter.
              * Unlike ParseIntoArray() function which expects single character delimitters, this function can accept a delimitter that is also a string.
              *
              * @param InputString - The string that is to be exploded.
              * @param Separator - The delimitter that is used for splitting (multi character strings are allowed)
              * @param limit - If greater than zero, returns only the first x strings. Otherwsie returns all the substrings
              * @param bTrimElelements - If True, then each subsctring is processed and any leading or trailing whitespcaes are trimmed.
              */
              UFUNCTION(BlueprintPure, meta = (FriendlyName = "Explode string", Keywords = "split explode string"), Category = String)
              static void String__ExplodeString(TArray<FString>& OutputStrings, FString InputString, FString Separator = ",", int32 limit = 0, bool bTrimElements = false);
              
          
          
              /** Load a texture 2D from a file path! Contributed by UE4 forum member n00854180t! */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
              static UTexture2D* GetTexture2DFromFile(const FString& FilePath);
              
              /** Contributed by UE4 forum member n00854180t! Plays a sound from file, attached to and following the specified component. This is a fire and forget sound. Replication is also not handled at this point.
              * @param FilePath - Path to sound file to play
              * @param AttachComponent - Component to attach to.
              * @param AttachPointName - Optional named point within the AttachComponent to play the sound at
              * @param Location - Depending on the value of Location Type this is either a relative offset from the attach component/point or an absolute world position that will be translated to a relative offset
              * @param LocationType - Specifies whether Location is a relative offset or an absolute world position
              * @param bStopWhenAttachedToDestroyed - Specifies whether the sound should stop playing when the owner of the attach to component is destroyed.
              * @param VolumeMultiplier - Volume multiplier
              * @param PitchMultiplier - PitchMultiplier
              * @param AttenuationSettings - Override attenuation settings package to play sound with
              */ 
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary", meta = (VolumeMultiplier = "1.0", PitchMultiplier = "1.0", AdvancedDisplay = "2", UnsafeDuringActorConstruction = "true"))
              static class UAudioComponent* PlaySoundAttachedFromFile(const FString& FilePath, class USceneComponent* AttachToComponent, FName AttachPointName = NAME_None, FVector Location = FVector(ForceInit), EAttachLocation::Type LocationType = EAttachLocation::SnapToTarget, bool bStopWhenAttachedToDestroyed = false, float VolumeMultiplier = 1.f, float PitchMultiplier = 1.f, float StartTime = 0.f, class USoundAttenuation* AttenuationSettings = NULL);
              
              /** Contributed by UE4 forum member n00854180t! Plays a sound at the given location. This is a fire and forget sound and does not travel with any actor. Replication is also not handled at this point.
              * @param FilePath - Path to sound file to play
              * @param Location - World position to play sound at
              * @param World - The World in which the sound is to be played
              * @param VolumeMultiplier - Volume multiplier
              * @param PitchMultiplier - PitchMultiplier
              * @param AttenuationSettings - Override attenuation settings package to play sound with
              */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary", meta = (HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject", VolumeMultiplier = "1.0", PitchMultiplier = "1.0", AdvancedDisplay = "3", UnsafeDuringActorConstruction = "true"))
              static void PlaySoundAtLocationFromFile(UObject* WorldContextObject, const FString& FilePath, FVector Location, float VolumeMultiplier = 1.f, float PitchMultiplier = 1.f, float StartTime = 0.f, class USoundAttenuation* AttenuationSettings = NULL);
              
              /** Contributed by UE4 forum member n00854180t! Creates a USoundWave* from file path.
              * Read .ogg header file and refresh USoundWave metadata.
              * @param FilePath        path to file to create sound wave from
              */
              UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
              static class USoundWave* GetSoundWaveFromFile(const FString& FilePath);
          
          
          private:
              // Thanks to @keru for the base code for loading an Ogg into a USoundWave: 
              // https://forums.unrealengine.com/showthread.php?7936-Custom-Music-Player&p=97659&viewfull=1#post97659
          
          
                   /**
                  * Read .ogg header file and refresh USoundWave metadata.
                  * @param sw             wave to put metadata
                  * @param rawFile        pointer to src file in memory
                  * @return 0     if everything is ok
                  *                 1 if couldn't read metadata.
                  */
                  static int32 fillSoundWaveInfo(USoundWave* sw, TArray<uint8>* rawFile);
          
          
          
          
          
          
                  /**
                  * Tries to find out FSoundSource object associated to the USoundWave.
                  * @param sw     wave, search key
                  * @return 0 if wave found and correctly set
                  *        -1 if error: sound device not set
                  *        -2 if error: sound wave not found
                  */
                  static int32 findSource(class USoundWave* sw, class FSoundSource* out_audioSource);
          
          
          
          
          
          
                  /**
                  * Contributed by: SaxonRah
                  * Better random numbers. Seeded with a random device. if the random device's entropy is 0; defaults to current time for seed.
                  * can override with seed functions;
                  */
          //----------------------------------------------------------------------------------------------BeginRANDOM
          public:
                  /** Construct a random device, returns either a random device or the default random engine; system dependant;
                  */
                  UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Random")
                      static void constructRand();
          
          
                  /** Seed Rand with value passed
                  * @param seed - value to pass to the prng as the seed
                  */
                  UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Random")
                      static void seedRand(int32 seed);
          
          
                  /** Seed Rand with current time
                  */
                  UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Random")
                      static void seedRandWithTime();
          
          
                  /** Seed Rand with entropy
                  * @param seed - value to pass to the prng as the seed
                  */
                  UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Random")
                      static void seedRandWithEntropy();
          
          
                  /** Random Bool - Bernoulli distribution
                  * @param fBias - Bias of Bernoulli distribution
                  * @return uniformly distributed bool based on bias parameter
                  */
                  UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Random")
                      static bool RandBool_Bernoulli(float fBias);
          
          
                  /** Random Integer - Zero to One Uniform distribution
                  * @return int32 - uniform distribution from 0 to 1
                  */
                  UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Random")
                      static int32 RandInt_uniDis();
          
          
                  /** Random Integer - MIN to MAX Uniform distribution
                  * @param iMin - Minimum value of uniform distribution
                  * @param iMax - Maximum value of uniform distribution
                  * @return int32 - uniform distribution from iMin to iMax parameters
                  */
                  UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Random")
                      static int32 RandInt_MINMAX_uniDis(int32 iMin, int32 iMax);
          
          
                  /** Random Double - Zero to One Uniform distribution
                  * @return double - uniform distribution from 0 to 1
                  */
                  UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Random")
                      static float RandFloat_uniDis();
          
          
                  /** Random Double - Uniform distribution based on MIN to MAX parameters
                  * @param iMin - Minimum value of uniform distribution
                  * @param iMax - Maximum value of uniform distribution
                  * @return double - uniform distribution from iMin to iMax parameters
                  */
                  UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Random")
                      static float RandFloat_MINMAX_uniDis(float iMin, float iMax);
                  
                  /** Random Bool - Bernoulli distribution - Mersenne Twister
                  * @param fBias - Bias of Bernoulli distribution
                  * @return uniformly distributed bool based on bias parameter
                  */
                  UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Random")
                      static bool RandBool_Bernoulli_MT(float fBias);
          
          
                  /** Random Integer - Zero to One Uniform distribution - Mersenne Twister
                  * @return int32 - uniform distribution from 0 to 1
                  */
                  UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Random")
                      static int32 RandInt_uniDis_MT();
          
          
                  /** Random Integer - MIN to MAX Uniform distribution - Mersenne Twister
                  * @param iMin - Minimum value of uniform distribution
                  * @param iMax - Maximum value of uniform distribution
                  * @return int32 - uniform distribution from iMin to iMax parameters
                  */
                  UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Random")
                      static int32 RandInt_MINMAX_uniDis_MT(int32 iMin, int32 iMax);
          
          
                  /** Random Float - Zero to One Uniform distribution -  Mersenne Twister
                  * @return float - uniform distribution from 0 to 1
                  */
                  UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Random")
                      static float RandFloat_uniDis_MT();
          
          
                  /** Random Float - Uniform distribution based on MIN to MAX parameters - Mersenne Twister
                  * @param iMin - Minimum value of uniform distribution
                  * @param iMax - Maximum value of uniform distribution
                  * @return float - uniform distribution from iMin to iMax parameters
                  */
                  UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Random")
                      static float RandFloat_MINMAX_uniDis_MT(float iMin, float iMax);
          //----------------------------------------------------------------------------------------------ENDRANDOM
          
          
          };
          Originally posted by VictoryBPFunctionLibrary.CPP
          Code:
          /*    By Rama
          */
          #include "VictoryBPLibraryPrivatePCH.h"
          
          
          #include "StaticMeshResources.h"
          
          
          //////////////////////////////////////////////////////////////////////////
          // UVictoryBPFunctionLibrary
          
          
          UVictoryBPFunctionLibrary::UVictoryBPFunctionLibrary(const FObjectInitializer& ObjectInitializer)
              : Super(ObjectInitializer)
          {
              
          }
           
          FVictoryInput UVictoryBPFunctionLibrary::VictoryGetVictoryInput(const FKeyEvent& KeyEvent)
          {
              FVictoryInput VInput;
               
              VInput.Key             = KeyEvent.GetKey();
              VInput.KeyAsString     = VInput.Key.GetDisplayName().ToString();
              
              VInput.bAlt         = KeyEvent.IsAltDown();
              VInput.bCtrl         = KeyEvent.IsControlDown();
              VInput.bShift     = KeyEvent.IsShiftDown();
              VInput.bCmd         = KeyEvent.IsCommandDown();
              
              return VInput;
          }
          
          
          
          
          void UVictoryBPFunctionLibrary::VictoryGetAllKeyBindings(TArray<FVictoryInput>& Bindings)
          {
              Bindings.Empty();
               
              const UInputSettings* Settings = GetDefault<UInputSettings>();
              if(!Settings) return;
              
              const TArray<FInputActionKeyMapping>& Actions = Settings->ActionMappings;
              
              for(const FInputActionKeyMapping& Each : Actions)
              {
                  Bindings.Add(FVictoryInput(Each));
              }
          }
          bool UVictoryBPFunctionLibrary::VictoryReBindKey(FVictoryInput Action)
          {
              UInputSettings* Settings = const_cast<UInputSettings*>(GetDefault<UInputSettings>());
              if(!Settings) return false;
          
          
              TArray<FInputActionKeyMapping>& Actions = Settings->ActionMappings;
              
              //~~~
              
              bool Found = false;
              for(FInputActionKeyMapping& Each : Actions)
              {
                  if(Each.ActionName.ToString() == Action.ActionName)
                  {  
                      UVictoryBPFunctionLibrary::UpdateActionMapping(Each,Action);
                      Found = true;
                      break;
                  }  
              }
              
              if(Found) 
              {
                  //SAVES TO DISK
                  const_cast<UInputSettings*>(Settings)->SaveKeyMappings();
                     
                  //REBUILDS INPUT, creates modified config in Saved/Config/Windows/Input.ini
                  for (TObjectIterator<UPlayerInput> It; It; ++It)
                  {
                      It->ForceRebuildingKeyMaps(true);
                  }
              }
              return Found;
          }
          
          
          void UVictoryBPFunctionLibrary::GetAllWidgetsOfClass(UObject* WorldContextObject, TSubclassOf<UUserWidget> WidgetClass, TArray<UUserWidget*>& FoundWidgets,bool TopLevelOnly)
          {
              //Prevent possibility of an ever-growing array if user uses this in a loop
              FoundWidgets.Empty();
              //~~~~~~~~~~~~
               
              if(!WidgetClass) return;
              if(!WorldContextObject) return;
               
              UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject);
              if(!World) return;
              //~~~~~~~~~~~
              
              for(TObjectIterator<UUserWidget> Itr; Itr; ++Itr)
              {
                  if(Itr->GetWorld() != World) continue;
                  //~~~~~~~~~~~~~~~~~~~~~
                  
                  if( ! Itr->IsA(WidgetClass)) continue;
                  //~~~~~~~~~~~~~~~~~~~
                   
                  //Top Level?
                  if(TopLevelOnly)
                  {
                      //only add top level widgets
                      if(Itr->IsInViewport())            
                      {
                          FoundWidgets.Add(*Itr);
                      }
                  }
                  else
                  {
                      //add all internal widgets
                      FoundWidgets.Add(*Itr);
                  }
              }
          } 
          void UVictoryBPFunctionLibrary::RemoveAllWidgetsOfClass(UObject* WorldContextObject, TSubclassOf<UUserWidget> WidgetClass)
          {
              if(!WidgetClass) return;
              if(!WorldContextObject) return;
               
              UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject);
              if(!World) return;
              //~~~~~~~~~~~
               
              for(TObjectIterator<UUserWidget> Itr; Itr; ++Itr)
              {
                  if(Itr->GetWorld() != World) continue;
                  //~~~~~~~~~~~~~~~~~~~~~
                  
                  if( ! Itr->IsA(WidgetClass)) continue;
                  //~~~~~~~~~~~~~~~~~~~
                   
                  //only add top level widgets
                  if(Itr->IsInViewport())            //IsInViewport in 4.6
                  {
                      Itr->RemoveFromViewport();
                  }
              }
          }
          
          
          bool UVictoryBPFunctionLibrary::IsWidgetOfClassInViewport(UObject* WorldContextObject, TSubclassOf<UUserWidget> WidgetClass)
          { 
              if(!WidgetClass) return false;
              if(!WorldContextObject) return false;
               
              UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject);
              if(!World) return false;
              //~~~~~~~~~~~
                
              for(TObjectIterator<UUserWidget> Itr; Itr; ++Itr)
              {
                  if(Itr->GetWorld() != World) continue;
                  //~~~~~~~~~~~~~~~~~~~~~
                  
                  if( ! Itr->IsA(WidgetClass)) continue;
                  //~~~~~~~~~~~~~~~~~~~
                      
                  if(Itr->GetIsVisible())            //IsInViewport in 4.6
                  {
                      return true;
                  }
              }
              
              return false;
          }
           
          
          
          bool UVictoryBPFunctionLibrary::VictorySoundVolumeChange(USoundClass* SoundClassObject, float NewVolume)
           {
              FAudioDevice* Device = GEngine->GetAudioDevice();
              if (!Device || !SoundClassObject)
              {
                  return false;
              }
                  
              bool bFound = Device->SoundClasses.Contains(SoundClassObject);
              if(bFound)
              { 
                  Device->SetClassVolume(SoundClassObject, NewVolume);
                  return true;
              }
              return false;
           }
          float UVictoryBPFunctionLibrary::VictoryGetSoundVolume(USoundClass* SoundClassObject)
          {
              FAudioDevice* Device = GEngine->GetAudioDevice();
              if (!Device || !SoundClassObject)
              {
                  return -1;
              }
                  
              FSoundClassProperties* Props = Device->GetSoundClassCurrentProperties(SoundClassObject);
              if(!Props) return -1;
              return Props->Volume;
          }
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          
          
          bool UVictoryBPFunctionLibrary::VictoryGetCustomConfigVar_Bool(FString SectionName,FString VariableName)
          {
              if(!GConfig) return false;
              //~~~~~~~~~~~
           
              bool Value;
              GConfig->GetBool(
                  *SectionName,
                  *VariableName,
                  Value,
                  GGameIni
              );
              return Value;
          }
          int32 UVictoryBPFunctionLibrary::VictoryGetCustomConfigVar_Int(FString SectionName,FString VariableName)
          {
              if(!GConfig) return 0;
              //~~~~~~~~~~~
           
              int32 Value;
              GConfig->GetInt(
                  *SectionName,
                  *VariableName,
                  Value,
                  GGameIni
              );
              return Value;
          }
          float UVictoryBPFunctionLibrary::VictoryGetCustomConfigVar_Float(FString SectionName,FString VariableName)
          {
              if(!GConfig) return 0;
              //~~~~~~~~~~~
           
              float Value;
              GConfig->GetFloat(
                  *SectionName,
                  *VariableName,
                  Value,
                  GGameIni
              );
              return Value;
          }
          FVector UVictoryBPFunctionLibrary::VictoryGetCustomConfigVar_Vector(FString SectionName,FString VariableName)
          {
              if(!GConfig) return FVector::ZeroVector;
              //~~~~~~~~~~~
           
              FVector Value;
              GConfig->GetVector(
                  *SectionName,
                  *VariableName,
                  Value,
                  GGameIni
              );
              return Value;
          }
          FRotator UVictoryBPFunctionLibrary::VictoryGetCustomConfigVar_Rotator(FString SectionName,FString VariableName)
          {
              if(!GConfig) return FRotator::ZeroRotator;
              //~~~~~~~~~~~
           
              FRotator Value;
              GConfig->GetRotator(
                  *SectionName,
                  *VariableName,
                  Value,
                  GGameIni
              );
              return Value;
          }
          FLinearColor UVictoryBPFunctionLibrary::VictoryGetCustomConfigVar_Color(FString SectionName,FString VariableName)
          {
              if(!GConfig) return FColor::Black;
              //~~~~~~~~~~~
            
              FColor Value;
              GConfig->GetColor(
                  *SectionName,
                  *VariableName,
                  Value,
                  GGameIni
              );
              return FLinearColor(Value);
          }
          FString UVictoryBPFunctionLibrary::VictoryGetCustomConfigVar_String(FString SectionName,FString VariableName)
          {
              if(!GConfig) return "";
              //~~~~~~~~~~~
           
              FString Value;
              GConfig->GetString(
                  *SectionName,
                  *VariableName,
                  Value,
                  GGameIni
              );
              return Value;
          }
          
          
          //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          
          
          void UVictoryBPFunctionLibrary::VictorySetCustomConfigVar_Bool(FString SectionName,FString VariableName, bool Value)
          {
              if(!GConfig) return;
              //~~~~~~~~~~~
           
              GConfig->SetBool(
                  *SectionName,
                  *VariableName,
                  Value,
                  GGameIni
              );
          }
          void UVictoryBPFunctionLibrary::VictorySetCustomConfigVar_Int(FString SectionName,FString VariableName, int32 Value)
          {
              if(!GConfig) return;
              //~~~~~~~~~~~
           
              GConfig->SetInt(
                  *SectionName,
                  *VariableName,
                  Value,
                  GGameIni
              );
          }
          void UVictoryBPFunctionLibrary::VictorySetCustomConfigVar_Float(FString SectionName,FString VariableName, float Value)
          {
              if(!GConfig) return;
              //~~~~~~~~~~~
              
              GConfig->SetFloat(
                  *SectionName,
                  *VariableName,
                  Value,
                  GGameIni
              );
          }
          void UVictoryBPFunctionLibrary::VictorySetCustomConfigVar_Vector(FString SectionName,FString VariableName, FVector Value)
          {
              if(!GConfig) return;
              //~~~~~~~~~~~
              
              GConfig->SetVector(
                  *SectionName,
                  *VariableName,
                  Value,
                  GGameIni
              );
          }
          void UVictoryBPFunctionLibrary::VictorySetCustomConfigVar_Rotator(FString SectionName,FString VariableName, FRotator Value)
          {
              if(!GConfig) return;
              //~~~~~~~~~~~
              
              GConfig->SetRotator(
                  *SectionName,
                  *VariableName,
                  Value,
                  GGameIni
              );
          }
          void UVictoryBPFunctionLibrary::VictorySetCustomConfigVar_Color(FString SectionName,FString VariableName, FLinearColor Value)
          {
              if(!GConfig) return;
              //~~~~~~~~~~~
               
              GConfig->SetColor(
                  *SectionName,
                  *VariableName,
                  FColor(Value),
                  GGameIni
              );
          }
          void UVictoryBPFunctionLibrary::VictorySetCustomConfigVar_String(FString SectionName,FString VariableName, FString Value)
          {
              if(!GConfig) return;
              //~~~~~~~~~~~
           
              GConfig->SetString(
                  *SectionName,
                  *VariableName,
                  *Value,
                  GGameIni
              );
          }
          
          
          
          
          
          
          
          
          
          
          
          
          //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          UObject* UVictoryBPFunctionLibrary::LoadObjectFromAssetPath(TSubclassOf<UObject> ObjectClass,FName Path,bool& IsValid)
          {
              IsValid = false;
              
              if(Path == NAME_None) return NULL;
              //~~~~~~~~~~~~~~~~~~~~~
              
              UObject* LoadedObj = StaticLoadObject( ObjectClass, NULL,*Path.ToString());
               
              IsValid = LoadedObj != nullptr;
              
              return LoadedObj;
          }
          FName UVictoryBPFunctionLibrary::GetObjectPath(UObject* Obj)
          {
              if(!Obj) return NAME_None;
              if(!Obj->IsValidLowLevel()) return NAME_None;
              //~~~~~~~~~~~~~~~~~~~~~~~~~
              
              FStringAssetReference ThePath = FStringAssetReference(Obj);
                  
              if(!ThePath.IsValid()) return "";
              
              //The Class FString Name For This Object
              FString str=Obj->GetClass()->GetDescription();
              
              //Remove spaces in Material Instance Constant class description!
              str = str.Replace(TEXT(" "),TEXT(""));
              
              str += "'";
              str += ThePath.ToString();
              str += "'";
              
              return FName(*str);
          }
          int32 UVictoryBPFunctionLibrary::GetPlayerUniqueNetID()
          {
              TObjectIterator<APlayerController> ThePC;
              if(!ThePC)                     return -1; 
              if(!ThePC->PlayerState) return -1;
              //~~~~~~~~~~~~~~~~~~~
              
              return ThePC->PlayerState->PlayerId;
          }
          UObject* UVictoryBPFunctionLibrary::CreateObject(UObject* WorldContextObject,UClass* TheObjectClass, FName Name)
          {
              if(!TheObjectClass) return NULL;
              //~~~~~~~~~~~~~~~~~
              
              //using a context object to get the world!
              UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject);
              if(!World) return NULL;
              //~~~~~~~~~~~
               
              return StaticConstructObject( TheObjectClass, World, Name);
          }
          UPrimitiveComponent* UVictoryBPFunctionLibrary::CreatePrimitiveComponent(
              UObject* WorldContextObject, 
              TSubclassOf<UPrimitiveComponent> CompClass, 
              FName Name,
              FVector Location, 
              FRotator Rotation
          ){
              if(!CompClass) return NULL;
              //~~~~~~~~~~~~~~~~~
              
              //using a context object to get the world!
              UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject);
              if(!World) return NULL;
              //~~~~~~~~~~~
               
              UPrimitiveComponent* NewComp = ConstructObject<UPrimitiveComponent>( CompClass, World, Name);
              if(!NewComp) return NULL;
              //~~~~~~~~~~~~~
               
              NewComp->SetWorldLocation(Location);
              NewComp->SetWorldRotation(Rotation);
              NewComp->RegisterComponentWithWorld(World);
              
              return NewComp;
          }
          
          
          AActor* UVictoryBPFunctionLibrary::SpawnActorIntoLevel(UObject* WorldContextObject, TSubclassOf<AActor> ActorClass, FName Level, FVector Location, FRotator Rotation,bool SpawnEvenIfColliding)
          {
              if(!ActorClass) return NULL;
              //~~~~~~~~~~~~~~~~~
              
              //using a context object to get the world!
              UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject);
              if(!World) return NULL;
              //~~~~~~~~~~~
              
              FActorSpawnParameters SpawnParameters;
              SpawnParameters.bNoCollisionFail         = SpawnEvenIfColliding;
              SpawnParameters.bDeferConstruction = false;
               
               
              //Get Level from Name!
              ULevel* FoundLevel = NULL;
              
              for(const ULevelStreaming* EachLevel : World->StreamingLevels)
              {
                  if( ! EachLevel) continue;
                  //~~~~~~~~~~~~~~~~
              
                  ULevel* LevelPtr = EachLevel->GetLoadedLevel();
                  
                  //Valid?
                  if(!LevelPtr) continue;
                  
                  if(EachLevel->GetWorldAssetPackageFName() == Level)
                  {
                      FoundLevel = LevelPtr; 
                      break;
                  } 
              }
              //~~~~~~~~~~~~~~~~~~~~~
              if(FoundLevel)
              {
                  SpawnParameters.OverrideLevel = FoundLevel;
              }
              //~~~~~~~~~~~~~~~~~~~~~
              
              return World->SpawnActor( ActorClass, &Location, &Rotation, SpawnParameters);
              
          }
          void UVictoryBPFunctionLibrary::GetNamesOfLoadedLevels(UObject* WorldContextObject, TArray<FString>& NamesOfLoadedLevels)
          {
              
              //using a context object to get the world!
              UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject);
              if(!World) return;
              //~~~~~~~~~~~
              
              NamesOfLoadedLevels.Empty();
              
              //Get Level from Name!
              ULevel* FoundLevel = NULL;
              
              for(const ULevelStreaming* EachLevel : World->StreamingLevels)
              {
                  if( ! EachLevel) continue;
                  //~~~~~~~~~~~~~~~~
              
                  ULevel* LevelPtr = EachLevel->GetLoadedLevel();
                  
                  //Valid?
                  if(!LevelPtr) continue;
                  
                  //Is This Level Visible?
                  if(!LevelPtr->bIsVisible) continue;
                  //~~~~~~~~~~~~~~~~~~~
                   
                  NamesOfLoadedLevels.Add(EachLevel->GetWorldAssetPackageFName().ToString());
              }
          }
                  
              
          void UVictoryBPFunctionLibrary::Loops_ResetBPRunawayCounter()
          {
              //Reset Runaway loop counter (use carefully)
              GInitRunaway();
          }
          
          
          void UVictoryBPFunctionLibrary::GraphicsSettings__SetFrameRateToBeUnbound()
          {
              if(!GEngine) return;
              //~~~~~~~~~
              
              GEngine->bSmoothFrameRate = 0; 
          }
          void UVictoryBPFunctionLibrary::GraphicsSettings__SetFrameRateCap(float NewValue)
          {
              if(!GEngine) return;
              //~~~~~~~~~
                 
              GEngine->bSmoothFrameRate = 1; 
              GEngine->SmoothedFrameRateRange = FFloatRange(10,NewValue);
          }
          
          
          FVector2D UVictoryBPFunctionLibrary::ProjectWorldToScreenPosition(const FVector& WorldLocation)
          {
              TObjectIterator<APlayerController> ThePC;
              if(!ThePC) return FVector2D::ZeroVector;
              
              ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(ThePC->Player);
              if (LocalPlayer != NULL && LocalPlayer->ViewportClient != NULL && LocalPlayer->ViewportClient->Viewport != NULL)
              {
                  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                  
                  // Create a view family for the game viewport
                  FSceneViewFamilyContext ViewFamily( FSceneViewFamily::ConstructionValues(
                      LocalPlayer->ViewportClient->Viewport,
                      ThePC->GetWorld()->Scene,
                      LocalPlayer->ViewportClient->EngineShowFlags )
                      .SetRealtimeUpdate(true) );
          
          
                  // Calculate a view where the player is to update the streaming from the players start location
                  FVector ViewLocation;
                  FRotator ViewRotation;
                  FSceneView* SceneView = LocalPlayer->CalcSceneView( &ViewFamily, /*out*/ ViewLocation, /*out*/ ViewRotation, LocalPlayer->ViewportClient->Viewport );
          
          
                  //Valid Scene View?
                  if (SceneView) 
                  {
                      //Return
                      FVector2D ScreenLocation;
                      SceneView->WorldToPixel(WorldLocation,ScreenLocation );
                      return ScreenLocation;
                  }
              } 
              
              return FVector2D::ZeroVector;
          }
          
          
          
          
          
          
          bool UVictoryBPFunctionLibrary::GetStaticMeshVertexLocations(UStaticMeshComponent* Comp, TArray<FVector>& VertexPositions)
          {
              if(!Comp) return false;
              if(!Comp->IsValidLowLevel()) return false;
              
              //~~~~~~~~~~~~~~~~~~~~
              //                Vertex Buffer
              if(! Comp)                                 return false;
              if(! Comp->StaticMesh)                     return false;
              if(! Comp->StaticMesh->RenderData)     return false;
              if( Comp->StaticMesh->RenderData->LODResources.Num() < 1) return false;
              //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              
              //~~~~~~~~~~~~
              VertexPositions.Empty();
              //~~~~~~~~~~~~
              
              FPositionVertexBuffer* VertexBuffer = NULL;
              VertexBuffer = & Comp->StaticMesh->RenderData->LODResources[0].PositionVertexBuffer;
              if(!VertexBuffer) return false;
              //~~~~~~~~~~~~~~~~
              
              int32 VertexCount = VertexBuffer->GetNumVertices();
               
              FTransform RV_Transform = Comp->GetComponentTransform(); 
              for(int32 Itr = 0; Itr < VertexCount; Itr++)
              {
                  VertexPositions.Add(
                      Comp->GetComponentLocation() + RV_Transform.TransformVector(VertexBuffer->VertexPosition(Itr))
                  );
              }
              
              return true;
          }
          
          
          
          
          void UVictoryBPFunctionLibrary::AddToActorRotation(AActor* TheActor, FRotator AddRot)
          {
              if (!TheActor) return;
              //~~~~~~~~~~~
          
          
              FTransform TheTransform = TheActor->GetTransform();
              TheTransform.ConcatenateRotation(AddRot.Quaternion());
              TheTransform.NormalizeRotation();
              TheActor->SetActorTransform(TheTransform);
          }
          
          
          
          
          
          
          
          
          void UVictoryBPFunctionLibrary::DrawCircle(
              UObject* WorldContextObject,
              FVector Center, 
              float Radius, 
              int32 NumPoints,
              float Thickness,
              FLinearColor LineColor,
              FVector YAxis,
              FVector ZAxis,
              float Duration,
              bool PersistentLines
          ){ 
              
              
              if(!WorldContextObject) return ;
              
              //using a context object to get the world!
              UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject);
              if(!World) return;
              //~~~~~~~~~~~
               
              /* //FOR PULL REQUEST TO EPIC
              FMatrix TM;
              TM.SetOrigin(Center);
              TM.SetAxis(0, FVector(1,0,0));
              TM.SetAxis(1, YAxis);
              TM.SetAxis(2, ZAxis);
              
              DrawDebugCircle(
                  World, 
                  TM, 
                  Radius, NumPoints, 
                  FColor::Red, 
                  false, 
                  -1.f, 
                  0
              );
          */
               
              // Need at least 4 segments  
              NumPoints = FMath::Max(NumPoints, 4);
              const float AngleStep = 2.f * PI / float(NumPoints);
          
          
              float Angle = 0.f;
              for(int32 v = 0; v < NumPoints; v++)
              {  
                  const FVector Vertex1 = Center + Radius * (YAxis * FMath::Cos(Angle) + ZAxis * FMath::Sin(Angle));
                  Angle += AngleStep;
                  const FVector Vertex2 = Center + Radius * (YAxis * FMath::Cos(Angle) + ZAxis * FMath::Sin(Angle));
                     
                  DrawDebugLine(
                      World, 
                      Vertex1, 
                      Vertex2,
                      LineColor,  
                      PersistentLines, 
                      Duration,
                      0,                 //depth  
                      Thickness          
                  );
              }
          }
          
          
          
          
          bool UVictoryBPFunctionLibrary::LoadStringArrayFromFile(TArray<FString>& StringArray, int32& ArraySize, FString FullFilePath, bool ExcludeEmptyLines)
          {
              ArraySize = 0;
              
              if(FullFilePath == "" || FullFilePath == " ") return false;
              
              //Empty any previous contents!
              StringArray.Empty();
              
              TArray<FString> FileArray;
              
              if( ! FFileHelper::LoadANSITextFileToStrings(*FullFilePath, NULL, FileArray))
              {
                  return false;
              }
              
              if(ExcludeEmptyLines)
              {
                  for(const FString& Each : FileArray )
                  {
                      if(Each == "") continue;
                      //~~~~~~~~~~~~~
                      
                      //check for any non whitespace
                      bool FoundNonWhiteSpace = false;
                      for(int32 v = 0; v < Each.Len(); v++)
                      {
                          if(Each[v] != ' ' && Each[v] != '\n')
                          {
                              FoundNonWhiteSpace = true;
                              break;
                          }
                          //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                      }
                      
                      if(FoundNonWhiteSpace)
                      {
                          StringArray.Add(Each);
                      }
                  }
              }
              else
              {
                  StringArray.Append(FileArray);
              }
              
              ArraySize = StringArray.Num();
              return true; 
          }
          
          
          
          
          void UVictoryBPFunctionLibrary::Selection_SelectionBox(UObject* WorldContextObject,TArray<AActor*>& SelectedActors, FVector2D AnchorPoint,FVector2D DraggedPoint,TSubclassOf<AActor> ClassFilter)
          {
              if(!WorldContextObject) return ;
              
              
              //using a context object to get the world!
              UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject);
              if(!World) return;
              //~~~~~~~~~~~
              
              SelectedActors.Empty();
              
              FBox2D Box;
              Box+=DraggedPoint;
              Box+=AnchorPoint;
              
              for(TActorIterator<AActor> Itr(World); Itr; ++Itr)
              {
                  if(!Itr->IsA(ClassFilter)) continue;
                  //~~~~~~~~~~~~~~~~~~
                  
                  if(Box.IsInside(UVictoryBPFunctionLibrary::ProjectWorldToScreenPosition(Itr->GetActorLocation())))
                  {
                      SelectedActors.Add(*Itr);
                  }
              }
          }
          
          
          bool UVictoryBPFunctionLibrary::PlayerController_GetControllerID(APlayerController* ThePC, int32& ControllerID)
          {
              if(!ThePC) return false;
              
              ULocalPlayer * LP = Cast<ULocalPlayer>(ThePC->Player);
              if(!LP) return false;
           
              ControllerID = LP->ControllerId;
              
              return true;
          }
              
          bool UVictoryBPFunctionLibrary::PlayerState_GetPlayerID(APlayerController* ThePC, int32& PlayerID)
          {
              if(!ThePC) return false;
              
              if(!ThePC->PlayerState) return false;
              
              PlayerID = ThePC->PlayerState->PlayerId;
              
              return true;
          }
          
          
          void UVictoryBPFunctionLibrary::Open_URL_In_Web_Browser(FString TheURL)
          {
              FPlatformProcess::LaunchURL( *TheURL, nullptr, nullptr );
          }
          
          
          void UVictoryBPFunctionLibrary::OperatingSystem__GetCurrentPlatform(
              bool& Windows_,         //some weird bug of making it all caps engine-side
              bool& Mac,
              bool& Linux, 
              bool& iOS, 
              bool& Android,
              bool& PS4,
              bool& XBoxOne,
              bool& HTML5,
              bool& WinRT_Arm,
              bool& WinRT
          ){
              //#define's in UE4 source code
              Windows_ =                 PLATFORM_WINDOWS;
              Mac =                         PLATFORM_MAC;
              Linux =                     PLATFORM_LINUX;
              
              PS4 =                         PLATFORM_PS4;
              XBoxOne =                 PLATFORM_XBOXONE;
              
              iOS =                         PLATFORM_IOS;
              Android =                 PLATFORM_ANDROID;
              
              HTML5 =                     PLATFORM_HTML5;
              
              WinRT_Arm =                 PLATFORM_WINRT_ARM;
              WinRT     =                 PLATFORM_WINRT;
          }
          
          
          FString UVictoryBPFunctionLibrary::RealWorldTime__GetCurrentOSTime( 
              int32& MilliSeconds,
              int32& Seconds, 
              int32& Minutes, 
              int32& Hours12,
              int32& Hours24,
              int32& Day,
              int32& Month,
              int32& Year
          ){
              const FDateTime Now = FDateTime::Now();
              
              MilliSeconds =         Now.GetMillisecond( );
              Seconds =             Now.GetSecond( );
              Minutes =                 Now.GetMinute( );
              Hours12 =             Now.GetHour12( );
              Hours24 =             Now.GetHour( ); //24
              Day =                     Now.GetDay( );
              Month =                 Now.GetMonth( );
              Year =                 Now.GetYear( );
              
              return Now.ToString();
          }
          
          
          void UVictoryBPFunctionLibrary::RealWorldTime__GetTimePassedSincePreviousTime(
                  const FString& PreviousTime,
                  float& Milliseconds,
                  float& Seconds,
                  float& Minutes,
                  float& Hours
          ){
              FDateTime ParsedDateTime;
              FDateTime::Parse(PreviousTime,ParsedDateTime);
              const FTimespan TimeDiff = FDateTime::Now() - ParsedDateTime;
              
              Milliseconds     = TimeDiff.GetTotalMilliseconds( );
              Seconds         = TimeDiff.GetTotalSeconds( );
              Minutes         = TimeDiff.GetTotalMinutes( );
              Hours             = TimeDiff.GetTotalHours( );
          }
              
          void UVictoryBPFunctionLibrary::RealWorldTime__GetDifferenceBetweenTimes(
                  const FString& PreviousTime1,
                  const FString& PreviousTime2,
                  float& Milliseconds,
                  float& Seconds,
                  float& Minutes,
                  float& Hours
          ){
              FDateTime ParsedDateTime1;
              FDateTime::Parse(PreviousTime1,ParsedDateTime1);
              
              FDateTime ParsedDateTime2;
              FDateTime::Parse(PreviousTime2,ParsedDateTime2);
              
              FTimespan TimeDiff; 
              
              if(PreviousTime1 < PreviousTime2)
              {
                  TimeDiff = ParsedDateTime2 - ParsedDateTime1;
              }
              else
              {
                  TimeDiff = ParsedDateTime1 - ParsedDateTime2;
              }
              
              Milliseconds     = TimeDiff.GetTotalMilliseconds( );
              Seconds         = TimeDiff.GetTotalSeconds( );
              Minutes         = TimeDiff.GetTotalMinutes( );
              Hours             = TimeDiff.GetTotalHours( );
          }
          
          
          
          
          
          
          void UVictoryBPFunctionLibrary::MaxOfFloatArray(const TArray<float>& FloatArray, int32& IndexOfMaxValue, float& MaxValue)
          {
              MaxValue = UVictoryBPFunctionLibrary::Max(FloatArray,&IndexOfMaxValue);
          }
          
          
          void UVictoryBPFunctionLibrary::MaxOfIntArray(const TArray<int32>& IntArray, int32& IndexOfMaxValue, int32& MaxValue)
          {
              MaxValue = UVictoryBPFunctionLibrary::Max(IntArray,&IndexOfMaxValue);
          }
          
          
          void UVictoryBPFunctionLibrary::MinOfFloatArray(const TArray<float>& FloatArray, int32& IndexOfMinValue, float& MinValue)
          {
              MinValue = UVictoryBPFunctionLibrary::Min(FloatArray,&IndexOfMinValue);
          }
          
          
          void UVictoryBPFunctionLibrary::MinOfIntArray(const TArray<int32>& IntArray, int32& IndexOfMinValue, int32& MinValue)
          {
              MinValue = UVictoryBPFunctionLibrary::Min(IntArray,&IndexOfMinValue);
          }
          
          
          
          
          
          
          bool UVictoryBPFunctionLibrary::CharacterMovement__SetMaxMoveSpeed(ACharacter* TheCharacter, float NewMaxMoveSpeed)
          {
              if(!TheCharacter)
              {
                  return false;
              }
              if(!TheCharacter->CharacterMovement)
              {
                  return false;
              }
              
              TheCharacter->CharacterMovement->MaxWalkSpeed = NewMaxMoveSpeed;
              
              return true;
          }
              
          
          
          
          
          int32 UVictoryBPFunctionLibrary::Conversion__FloatToRoundedInteger(float IN_Float)
          {
              return FGenericPlatformMath::RoundToInt(IN_Float);
          }
          
          
          FString UVictoryBPFunctionLibrary::String__CombineStrings(FString StringFirst, FString StringSecond, FString Separator, FString StringFirstLabel, FString StringSecondLabel)
          {
              return StringFirstLabel + StringFirst + Separator + StringSecondLabel + StringSecond;
          }
          
          
          bool UVictoryBPFunctionLibrary::OptionsMenu__GetDisplayAdapterScreenResolutions(TArray<int32>& Widths, TArray<int32>& Heights, TArray<int32>& RefreshRates,bool IncludeRefreshRates)
          {
              //Clear any Previous
              Widths.Empty();
              Heights.Empty();
              RefreshRates.Empty();
              
              TArray<FString> Unique;    
              
              FScreenResolutionArray Resolutions;
              if(RHIGetAvailableResolutions(Resolutions, false))
              {
                  for (const FScreenResolutionRHI& EachResolution : Resolutions)
                  {
                      FString Str = "";
                      Str += FString::FromInt(EachResolution.Width);
                      Str += FString::FromInt(EachResolution.Height);
                      
                      //Include Refresh Rates?
                      if(IncludeRefreshRates)
                      {
                          Str += FString::FromInt(EachResolution.RefreshRate);
                      }        
                      
                      if(Unique.Contains(Str))
                      {
                          //Skip! This is duplicate!
                          continue;
                      }
                      else
                      {
                          //Add to Unique List!
                          Unique.AddUnique(Str);
                      }
                      
                      //Add to Actual Data Output!
                      Widths.Add(            EachResolution.Width);
                      Heights.Add(            EachResolution.Height);
                      RefreshRates.Add(    EachResolution.RefreshRate);
                  }
          
          
                  return true;
              }
              return false;
          }
          
          
          AStaticMeshActor* UVictoryBPFunctionLibrary::Clone__StaticMeshActor(UObject* WorldContextObject, bool&IsValid, AStaticMeshActor* ToClone, FVector LocationOffset,FRotator RotationOffset)
          {
              IsValid = NULL;
              if(!ToClone) return NULL;
              if(!ToClone->IsValidLowLevel()) return NULL;
              //~~~~~~~~~~~~~~~~~~~~~~~~~~~
              
              if(!WorldContextObject) return NULL;
              
              //using a context object to get the world!
              UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject);
              if(!World) return NULL;
              //~~~~~~~~~~~
              
              //For BPS
              UClass* SpawnClass = ToClone->GetClass();
              
              FActorSpawnParameters SpawnInfo;
              SpawnInfo.bNoCollisionFail         = true;
              SpawnInfo.Owner                 = ToClone;
              SpawnInfo.Instigator                = NULL;
              SpawnInfo.bDeferConstruction     = NULL;
              
              AStaticMeshActor* NewSMA = World->SpawnActor<AStaticMeshActor>(SpawnClass, ToClone->GetActorLocation() + FVector(0,0,512) ,ToClone->GetActorRotation(), SpawnInfo );
              
              if(!NewSMA) return NULL;
              
              //Copy Transform
              NewSMA->SetActorTransform(ToClone->GetTransform());
              
              //Mobility
              NewSMA->StaticMeshComponent->SetMobility(EComponentMobility::Movable    );
              
              //copy static mesh
              NewSMA->StaticMeshComponent->SetStaticMesh(ToClone->StaticMeshComponent->StaticMesh);
              
              //~~~
              
              //copy materials
              TArray<UMaterialInterface*> Mats;
              ToClone->StaticMeshComponent->GetUsedMaterials(Mats);
              
              const int32 Total = Mats.Num();
              for(int32 v = 0; v < Total; v++ )
              {
                  NewSMA->StaticMeshComponent->SetMaterial(v,Mats[v]);
              }
              
              //~~~
              
              //copy physics state
              if(ToClone->StaticMeshComponent->IsSimulatingPhysics())
              {
                  NewSMA->StaticMeshComponent->SetSimulatePhysics(true);
              }
              
              //~~~
              
              //Add Location Offset
              const FVector SpawnLoc = ToClone->GetActorLocation() + LocationOffset;
              NewSMA->SetActorLocation(SpawnLoc);
              
              //Add Rotation offset
              FTransform TheTransform = NewSMA->GetTransform();
              TheTransform.ConcatenateRotation(RotationOffset.Quaternion());
              TheTransform.NormalizeRotation();
              
              //Set Transform
              NewSMA->SetActorTransform(TheTransform);
              
              IsValid = true;
              return NewSMA;
          }
          
          
          bool UVictoryBPFunctionLibrary::Actor__TeleportToActor(AActor* ActorToTeleport, AActor* DestinationActor)
          {
              if(!ActorToTeleport)                             return false;
              if(!ActorToTeleport->IsValidLowLevel())     return false;
              if(!DestinationActor)                             return false;
              if(!DestinationActor->IsValidLowLevel())     return false;
              
              //Set Loc
              ActorToTeleport->SetActorLocation(DestinationActor->GetActorLocation());
              
              //Set Rot
              ActorToTeleport->SetActorRotation(DestinationActor->GetActorRotation());
              
              return true;
          }
          
          
          bool UVictoryBPFunctionLibrary::WorldType__InEditorWorld(UObject* WorldContextObject)
          {
              if(!WorldContextObject) return false;
              
              //using a context object to get the world!
              UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject);
              if(!World) return false;
              //~~~~~~~~~~~
              
              return (World->WorldType == EWorldType::Editor );
          }
          
          
          bool UVictoryBPFunctionLibrary::WorldType__InPIEWorld(UObject* WorldContextObject)
          {
              if(!WorldContextObject) return false;
              
              //using a context object to get the world!
              UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject);
              if(!World) return false;
              //~~~~~~~~~~~
              
              return (World->WorldType == EWorldType::PIE );
          }
          bool UVictoryBPFunctionLibrary::WorldType__InGameInstanceWorld(UObject* WorldContextObject)
          {
              if(!WorldContextObject) return false;
              
              //using a context object to get the world!
              UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject);
              if(!World) return false;
              //~~~~~~~~~~~
              
              return (World->WorldType == EWorldType::Game );
          }
              
          FString UVictoryBPFunctionLibrary::Accessor__GetNameAsString(const UObject* TheObject)
          {
              if (!TheObject) return "";
              return TheObject->GetName();
          }
          
          
          FRotator UVictoryBPFunctionLibrary::Conversions__VectorToRotator(const FVector& TheVector)
          {
              return TheVector.Rotation();
          }
          FVector UVictoryBPFunctionLibrary::Conversions__RotatorToVector(const FRotator& TheRotator)
          {
              return TheRotator.Vector();
          }
          FRotator UVictoryBPFunctionLibrary::Character__GetControllerRotation(AActor * TheCharacter)
          {
              ACharacter * AsCharacter = Cast<ACharacter>(TheCharacter);
          
          
              if (!AsCharacter) return FRotator::ZeroRotator;
              
              return AsCharacter->GetControlRotation();
          }
          
          
          //Draw From Socket on Character's Mesh
          void UVictoryBPFunctionLibrary::Draw__Thick3DLineFromCharacterSocket(AActor* TheCharacter,  const FVector& EndPoint, FName Socket, FLinearColor LineColor, float Thickness, float Duration)
          {
              ACharacter * AsCharacter = Cast<ACharacter>(TheCharacter);
              if (!AsCharacter) return;
              if (!AsCharacter->Mesh) return;
              //~~~~~~~~~~~~~~~~~~~~
              
              //Get World
              UWorld* TheWorld = AsCharacter->GetWorld();
              if (!TheWorld) return;
              //~~~~~~~~~~~~~~~~~
              
              const FVector SocketLocation = AsCharacter->Mesh->GetSocketLocation(Socket);
              DrawDebugLine(
                  TheWorld, 
                  SocketLocation, 
                  EndPoint, 
                  FColor(LineColor), 
                  false, 
                  Duration, 
                  0, 
                  Thickness
              );
              
          }
          /** Draw 3D Line of Chosen Thickness From Mesh Socket to Destination */
          void UVictoryBPFunctionLibrary::Draw__Thick3DLineFromSocket(USkeletalMeshComponent* Mesh, const FVector& EndPoint, FName Socket, FLinearColor LineColor, float Thickness, float Duration)
          {
              if (!Mesh) return;
              //~~~~~~~~~~~~~~
              
              //Get an actor to GetWorld() from
              TObjectIterator<APlayerController> Itr;
              if (!Itr) return;
              //~~~~~~~~~~~~
              
              //Get World
              UWorld* TheWorld = Itr->GetWorld();
              if (!TheWorld) return;
              //~~~~~~~~~~~~~~~~~
              
              const FVector SocketLocation = Mesh->GetSocketLocation(Socket);
              
              DrawDebugLine(
                  TheWorld, 
                  SocketLocation, 
                  EndPoint, 
                  FColor(LineColor), 
                  false, 
                  Duration, 
                  0, 
                  Thickness
              );
          }
          /** Draw 3D Line of Chosen Thickness Between Two Actors */
          void UVictoryBPFunctionLibrary::Draw__Thick3DLineBetweenActors(AActor * StartActor, AActor * EndActor, FLinearColor LineColor, float Thickness, float Duration)
          {
              if (!StartActor) return;
              if (!EndActor) return;
              //~~~~~~~~~~~~~~~~
              
              DrawDebugLine(
                  StartActor->GetWorld(), 
                  StartActor->GetActorLocation(), 
                  EndActor->GetActorLocation(), 
                  FColor(LineColor), 
                  false, 
                  Duration, 
                  0, 
                  Thickness
              );
          }
              
          bool UVictoryBPFunctionLibrary::Animation__GetAimOffsets(AActor* AnimBPOwner, float& Pitch, float& Yaw)
          {
              //Get Owning Character
              ACharacter * TheCharacter = Cast<ACharacter>(AnimBPOwner);
              
              if (!TheCharacter) return false;
              //~~~~~~~~~~~~~~~
              
              //Get Owning Controller Rotation
              const FRotator TheCtrlRotation = TheCharacter->GetControlRotation();
              
              const FVector RotationDir = TheCtrlRotation.Vector();
              
              //Inverse of ActorToWorld matrix is Actor to Local Space
                  //so this takes the direction vector, the PC or AI rotation
                  //and outputs what this dir is 
                  //in local actor space &
                  
                  //local actor space is what we want for aiming offsets
                  
              const FVector LocalDir = TheCharacter->ActorToWorld().InverseTransformVectorNoScale(RotationDir);
              const FRotator LocalRotation = LocalDir.Rotation();
                  
              //Pass out Yaw and Pitch
              Yaw = LocalRotation.Yaw;
              Pitch = LocalRotation.Pitch;
              
              return true;
          }
          bool UVictoryBPFunctionLibrary::Animation__GetAimOffsetsFromRotation(AActor * AnimBPOwner, const FRotator & TheRotation, float & Pitch, float & Yaw)
          {
              //Get Owning Character
              ACharacter * TheCharacter = Cast<ACharacter>(AnimBPOwner);
              
              if (!TheCharacter) return false;
              //~~~~~~~~~~~~~~~
              
              //using supplied rotation
              const FVector RotationDir = TheRotation.Vector();
              
              //Inverse of ActorToWorld matrix is Actor to Local Space
                  //so this takes the direction vector, the PC or AI rotation
                  //and outputs what this dir is 
                  //in local actor space &
                  
                  //local actor space is what we want for aiming offsets
                  
              const FVector LocalDir = TheCharacter->ActorToWorld().InverseTransformVectorNoScale(RotationDir);
              const FRotator LocalRotation = LocalDir.Rotation();
                  
              //Pass out Yaw and Pitch
              Yaw = LocalRotation.Yaw;
              Pitch = LocalRotation.Pitch;
              
              return true;
          }
          
          
          void UVictoryBPFunctionLibrary::Visibility__GetRenderedActors(TArray<AActor*>& CurrentlyRenderedActors, float MinRecentTime)
          {
              //Empty any previous entries
              CurrentlyRenderedActors.Empty();
              
              //Iterate Over Actors
              for ( TObjectIterator<AActor> Itr; Itr; ++Itr )
              {
                  if (Itr->GetLastRenderTime() > MinRecentTime)
                  {
                      CurrentlyRenderedActors.Add( * Itr);
                  }
              }
          }
          void UVictoryBPFunctionLibrary::Visibility__GetNotRenderedActors(TArray<AActor*>& CurrentlyNotRenderedActors, float MinRecentTime)
          {
              //Empty any previous entries
              CurrentlyNotRenderedActors.Empty();
              
              //Iterate Over Actors
              for ( TObjectIterator<AActor> Itr; Itr; ++Itr )
              {
                  if (Itr->GetLastRenderTime() <= MinRecentTime)
                  {
                      CurrentlyNotRenderedActors.Add( * Itr);
                  }
              }
          }
          
          
          void UVictoryBPFunctionLibrary::Rendering__FreezeGameRendering()
          {
              FViewport::SetGameRenderingEnabled(false);
          }
          void UVictoryBPFunctionLibrary::Rendering__UnFreezeGameRendering()
          {
              FViewport::SetGameRenderingEnabled(true);
          }
              
          bool UVictoryBPFunctionLibrary::ClientWindow__GameWindowIsForeGroundInOS()
          {
              //Iterate Over Actors
              UWorld* TheWorld = NULL;
              for ( TObjectIterator<AActor> Itr; Itr; ++Itr )
              {
                  TheWorld = Itr->GetWorld();
                  if (TheWorld) break;
                  //~~~~~~~~~~~~~~~~~~~~~~~
              }
              //Get Player
              ULocalPlayer* VictoryPlayer = 
                      TheWorld->GetFirstLocalPlayerFromController(); 
          
          
              if (!VictoryPlayer) return false;
              //~~~~~~~~~~~~~~~~~~~~
              
              //get view port ptr
              UGameViewportClient * VictoryViewportClient = 
                  Cast < UGameViewportClient > (VictoryPlayer->ViewportClient);
                  
              if (!VictoryViewportClient) return false;
              //~~~~~~~~~~~~~~~~~~~~
               
              FViewport * VictoryViewport = VictoryViewportClient->Viewport;
              
              if (!VictoryViewport) return false;
              //~~~~~~~~~~~~~~~~~~~~
              
              return VictoryViewport->IsForegroundWindow();
          }
          bool UVictoryBPFunctionLibrary::FileIO__SaveStringTextToFile(
              FString SaveDirectory, 
              FString JoyfulFileName, 
              FString SaveText,
              bool AllowOverWriting
          ){
              //Dir Exists?
              if ( !FPlatformFileManager::Get().GetPlatformFile().DirectoryExists( *SaveDirectory))
              {
                  //create directory if it not exist
                  FPlatformFileManager::Get().GetPlatformFile().CreateDirectory( *SaveDirectory);
                  
                  //still could not make directory?
                  if (!FPlatformFileManager::Get().GetPlatformFile().DirectoryExists( *SaveDirectory))
                  {
                      //Could not make the specified directory
                      return false;
                      //~~~~~~~~~~~~~~~~~~~~~~
                  }
              }
              
              //get complete file path
              SaveDirectory += "\\";
              SaveDirectory += JoyfulFileName;
              
              //No over-writing?
              if (!AllowOverWriting)
              {
                  //Check if file exists already
                  if (FPlatformFileManager::Get().GetPlatformFile().FileExists( * SaveDirectory))
                  {
                      //no overwriting
                      return false;
                  }
              }
              
              return FFileHelper::SaveStringToFile(SaveText, * SaveDirectory);
          }
          
          
          float UVictoryBPFunctionLibrary::Calcs__ClosestPointToSourcePoint(const FVector & Source, const TArray<FVector>& OtherPoints, FVector& ClosestPoint)
          {
              float CurDist = 0;
              float ClosestDistance = -1;
              int32 ClosestVibe = 0;
              ClosestPoint = FVector::ZeroVector;
              
              if (OtherPoints.Num() <= 0) return ClosestDistance;
              //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              
              for (int32 Itr = 0; Itr < OtherPoints.Num(); Itr++)
              {
                  if (Source == OtherPoints[Itr]) continue;
                  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                  
                  //Dist
                  CurDist = FVector::Dist(Source, OtherPoints[Itr]);
                  
                  //Min
                  if (ClosestDistance < 0 || ClosestDistance >= CurDist)
                  {
                      ClosestVibe = Itr;
                      ClosestDistance = CurDist;
                  }
              }
              
              //Out
              ClosestPoint = OtherPoints[ClosestVibe];
              return ClosestDistance;
          }
          
          
          bool UVictoryBPFunctionLibrary::Data__GetCharacterBoneLocations(AActor * TheCharacter, TArray<FVector>& BoneLocations)
          {
              ACharacter * Source = Cast<ACharacter>(TheCharacter);
              if (!Source) return false;
              
              if (!Source-> Mesh) return false;
              //~~~~~~~~~~~~~~~~~~~~~~~~~
              TArray<FName> BoneNames;
              
              BoneLocations.Empty();
              
              
              //Get Bone Names
              Source-> Mesh->GetBoneNames(BoneNames);
              
              //Get Bone Locations
              for (int32 Itr = 0; Itr < BoneNames.Num(); Itr++ )
              {
                  BoneLocations.Add(Source->Mesh->GetBoneLocation(BoneNames[Itr]));
              }
              
              return true;
          }
          
          
          USkeletalMeshComponent* UVictoryBPFunctionLibrary::Accessor__GetCharacterSkeletalMesh(AActor * TheCharacter, bool& IsValid)
          {
              IsValid = false;
              
              ACharacter * AsCharacter = Cast<ACharacter>(TheCharacter);
              if (!AsCharacter) return NULL;
              //~~~~~~~~~~~~~~~~~
              
              //Is Valid?
              if (AsCharacter->Mesh)
                  if (AsCharacter->Mesh->IsValidLowLevel() ) 
                      IsValid = true;
                      
              return AsCharacter->Mesh;
          }
          
          
          bool UVictoryBPFunctionLibrary::TraceData__GetTraceDataFromCharacterSocket(
              FVector & TraceStart, //out
              FVector & TraceEnd,    //out
              AActor * TheCharacter,
              const FRotator& TraceRotation, 
              float TraceLength,
              FName Socket, 
              bool DrawTraceData, 
              FLinearColor TraceDataColor, 
              float TraceDataThickness
          ) {
              ACharacter * AsCharacter = Cast<ACharacter>(TheCharacter);
              if (!AsCharacter) return false;
              
              //Mesh Exists?
              if (!AsCharacter->Mesh) return false;
              
              //Socket Exists?
              if (!AsCharacter->Mesh->DoesSocketExist(Socket)) return false;
              //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              
              TraceStart = AsCharacter->Mesh->GetSocketLocation(Socket);
              TraceEnd = TraceStart + TraceRotation.Vector() * TraceLength;
              
              if (DrawTraceData) 
              {
                  //Get World
                  UWorld* TheWorld = AsCharacter->GetWorld();
                  if (!TheWorld) return false;
                  //~~~~~~~~~~~~~~~~~
              
                  DrawDebugLine(
                      TheWorld, 
                      TraceStart, 
                      TraceEnd, 
                      FColor(TraceDataColor), 
                      false, 
                      0.0333, 
                      0, 
                      TraceDataThickness
                  );
              }
              
              return true;
          }
          bool UVictoryBPFunctionLibrary::TraceData__GetTraceDataFromSkeletalMeshSocket(
              FVector & TraceStart, //out
              FVector & TraceEnd,    //out
              USkeletalMeshComponent * Mesh,
              const FRotator & TraceRotation,    
              float TraceLength,
              FName Socket, 
              bool DrawTraceData, 
              FLinearColor TraceDataColor, 
              float TraceDataThickness
          ) {
              //Mesh Exists?
              if (!Mesh) return false;
              
              //Socket Exists?
              if (!Mesh->DoesSocketExist(Socket)) return false;
              //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          
          
              TraceStart = Mesh->GetSocketLocation(Socket);
              TraceEnd = TraceStart + TraceRotation.Vector() * TraceLength;
              
              if (DrawTraceData) 
              {
                  //Get a PC to GetWorld() from
                  TObjectIterator<APlayerController> Itr;
                  if (!Itr) return false;
                  
                  //~~~~~~~~~~~~
                  
                  //Get World
                  UWorld* TheWorld = Itr->GetWorld();
                  if (!TheWorld) return false;
                  //~~~~~~~~~~~~~~~~~
              
                  DrawDebugLine(
                      TheWorld, 
                      TraceStart, 
                      TraceEnd, 
                      FColor(TraceDataColor), 
                      false, 
                      0.0333, 
                      0, 
                      TraceDataThickness
                  );
              }
              
              return true;
          }
          AActor*  UVictoryBPFunctionLibrary::Traces__CharacterMeshTrace___ClosestBone(
              AActor* TraceOwner,
              const FVector & TraceStart, 
              const FVector & TraceEnd, 
              FVector & OutImpactPoint, 
              FVector & OutImpactNormal, 
              FName & ClosestBoneName,
              FVector & ClosestBoneLocation,
              bool& IsValid
          )
          {
              IsValid = false;
              AActor * HitActor = NULL;
              //~~~~~~~~~~~~~~~~~~~~~~
              
              //Get a PC to GetWorld() from
              TObjectIterator<APlayerController> Itr;
              if (!Itr) return NULL;
              
              //~~~~~~~~~~~~
              
              //Get World
              UWorld* TheWorld = Itr->GetWorld();
              if (TheWorld == nullptr) return NULL;
              //~~~~~~~~~~~~~~~~~
              
              
              //Simple Trace First
              FCollisionQueryParams TraceParams(FName(TEXT("VictoryBPTrace::CharacterMeshTrace")), true, HitActor);
              TraceParams.bTraceComplex = true;
              TraceParams.bTraceAsyncScene = true;
              TraceParams.bReturnPhysicalMaterial = false;
              TraceParams.AddIgnoredActor(TraceOwner);
              
              //initialize hit info
              FHitResult RV_Hit(ForceInit);
              
              TheWorld->LineTraceSingle(
                  RV_Hit,        //result
                  TraceStart, 
                  TraceEnd, 
                  ECC_Pawn, //collision channel
                  TraceParams
              );
                  
              //Hit Something!
              if (!RV_Hit.bBlockingHit) return HitActor;
              
              
              //Character?
              HitActor = RV_Hit.GetActor();
              ACharacter * AsCharacter = Cast<ACharacter>(HitActor);
              if (!AsCharacter) return HitActor;
              
              //Mesh
              if (!AsCharacter->Mesh) return HitActor;
              
              //Component Trace
              IsValid = AsCharacter->Mesh->K2_LineTraceComponent(
                  TraceStart, 
                  TraceEnd, 
                  true, 
                  false, 
                  OutImpactPoint, 
                  OutImpactNormal,
                  ClosestBoneName
              ); 
              
              //Location
              ClosestBoneLocation = AsCharacter->Mesh->GetBoneLocation(ClosestBoneName);
              
              return HitActor;
          }
          
          
          AActor* UVictoryBPFunctionLibrary::Traces__CharacterMeshTrace___ClosestSocket(
              const AActor * TraceOwner, 
              const FVector & TraceStart, 
              const FVector & TraceEnd, 
              FVector & OutImpactPoint, 
              FVector & OutImpactNormal, 
              FName & ClosestSocketName, 
              FVector & SocketLocation, 
              bool & IsValid
          )
          {
              IsValid = false;
              AActor * HitActor = NULL;
              //~~~~~~~~~~~~~~~~~~~~~~
               
              //There may not be a trace owner so dont rely on it
              
              //Get a PC to GetWorld() from
              TObjectIterator<APlayerController> Itr;
              if (!Itr) return NULL;
              
              //~~~~~~~~~~~~
              
              //Get World
              UWorld* TheWorld = Itr->GetWorld();
              if (TheWorld == nullptr) return NULL;
              //~~~~~~~~~~~~~~~~~
              
              
              //Simple Trace First
              FCollisionQueryParams TraceParams(FName(TEXT("VictoryBPTrace::CharacterMeshSocketTrace")), true, HitActor);
              TraceParams.bTraceComplex = true;
              TraceParams.bTraceAsyncScene = true;
              TraceParams.bReturnPhysicalMaterial = false;
              TraceParams.AddIgnoredActor(TraceOwner);
              
              //initialize hit info
              FHitResult RV_Hit(ForceInit);
              
              TheWorld->LineTraceSingle(
                  RV_Hit,        //result
                  TraceStart, 
                  TraceEnd, 
                  ECC_Pawn, //collision channel
                  TraceParams
              );
                  
              //Hit Something!
              if (!RV_Hit.bBlockingHit) return HitActor;
              
              
              //Character?
              HitActor = RV_Hit.GetActor();
              ACharacter * AsCharacter = Cast<ACharacter>(HitActor);
              if (!AsCharacter) return HitActor;
              
              //Mesh
              if (!AsCharacter->Mesh) return HitActor;
              
              //Component Trace
              FName BoneName;
              if (! AsCharacter->Mesh->K2_LineTraceComponent(
                  TraceStart, 
                  TraceEnd, 
                  true, 
                  false, 
                  OutImpactPoint, 
                  OutImpactNormal,
                  BoneName
              )) return HitActor;
              
              //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              //                    Socket Names
              TArray<FComponentSocketDescription> SocketNames;
              
              //Get Bone Names
              AsCharacter->Mesh->QuerySupportedSockets(SocketNames);
              
              //                        Min
              FVector CurLoc;
              float CurDist = 0;
              float ClosestDistance = -1;
              int32 ClosestVibe = 0;
              
              //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              //Check All Bones Locations
              for (int32 Itr = 0; Itr < SocketNames.Num(); Itr++ )
              {
                  //Is this a Bone not a socket?
                  if(SocketNames[Itr].Type == EComponentSocketType::Bone) continue;
                  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                  
                  CurLoc = AsCharacter->Mesh->GetSocketLocation(SocketNames[Itr].Name);
                  
                  //Dist
                  CurDist = FVector::Dist(OutImpactPoint, CurLoc);
                  
                  //Min
                  if (ClosestDistance < 0 || ClosestDistance >= CurDist)
                  {
                      ClosestVibe = Itr;
                      ClosestDistance = CurDist;
                  }
              }
              
              //Name
              ClosestSocketName = SocketNames[ClosestVibe].Name;
              
              //Location
              SocketLocation = AsCharacter->Mesh->GetSocketLocation(ClosestSocketName);
              
              //Valid
              IsValid = true;
              
              //Actor
              return HitActor;
          }
              
          //Most HUD stuff is in floats so I do the conversion internally
          bool UVictoryBPFunctionLibrary::Viewport__SetMousePosition(const APlayerController* ThePC, const float& PosX, const float& PosY)
          {
              if (!ThePC) return false;
              //~~~~~~~~~~~~~
              
              //Get Player
              const ULocalPlayer * VictoryPlayer = Cast<ULocalPlayer>(ThePC->Player); 
                                                      //PlayerController::Player is UPlayer
                     
              if (!VictoryPlayer) return false;
              //~~~~~~~~~~~~~~~~~~~~
              
              //get view port ptr
              const UGameViewportClient * VictoryViewportClient = 
                  Cast < UGameViewportClient > (VictoryPlayer->ViewportClient);
                  
              if (!VictoryViewportClient) return false;
              //~~~~~~~~~~~~~~~~~~~~
               
              FViewport * VictoryViewport = VictoryViewportClient->Viewport;
              
              if (!VictoryViewport) return false;
              //~~~~~~~~~~~~~~~~~~~~
              
              //Set Mouse
              VictoryViewport->SetMouse(int32(PosX), int32(PosY));
              
              return true;
          }
          
          
          APlayerController * UVictoryBPFunctionLibrary::Accessor__GetPlayerController(
              AActor * TheCharacter, 
              bool & IsValid
          )
          {
              IsValid = false;
              
              //Cast to Character
              ACharacter * AsCharacter = Cast<ACharacter>(TheCharacter);
              if (!AsCharacter) return NULL;
              
              //cast to PC
              APlayerController * ThePC = Cast < APlayerController > (AsCharacter->GetController());
              
              if (!ThePC ) return NULL;
              
              IsValid = true;
              return ThePC;
          }
              
          bool UVictoryBPFunctionLibrary::Viewport__GetCenterOfViewport(const APlayerController * ThePC, float & PosX, float & PosY)
          {
              if (!ThePC) return false;
              //~~~~~~~~~~~~~
              
              //Get Player
              const ULocalPlayer * VictoryPlayer = Cast<ULocalPlayer>(ThePC->Player); 
                                                      //PlayerController::Player is UPlayer
                     
              if (!VictoryPlayer) return false;
              //~~~~~~~~~~~~~~~~~~~~
              
              //get view port ptr
              const UGameViewportClient * VictoryViewportClient = 
                  Cast < UGameViewportClient > (VictoryPlayer->ViewportClient);
                  
              if (!VictoryViewportClient) return false;
              //~~~~~~~~~~~~~~~~~~~~
               
              FViewport * VictoryViewport = VictoryViewportClient->Viewport;
              
              if (!VictoryViewport) return false;
              //~~~~~~~~~~~~~~~~~~~~
              
              //Get Size
              FIntPoint Size = VictoryViewport->GetSizeXY();
              
              //Center
              PosX = Size.X / 2;
              PosY = Size.Y / 2;
              
              return true;
          }
          
          
          bool UVictoryBPFunctionLibrary::Viewport__GetMousePosition(const APlayerController * ThePC, float & PosX, float & PosY)
          {
              if (!ThePC) return false;
              //~~~~~~~~~~~~~
              
              //Get Player
              const ULocalPlayer * VictoryPlayer = Cast<ULocalPlayer>(ThePC->Player); 
                                                      //PlayerController::Player is UPlayer
                     
              if (!VictoryPlayer) return false;
              //~~~~~~~~~~~~~~~~~~~~
              
              //get view port ptr
              const UGameViewportClient * VictoryViewportClient = 
                  Cast < UGameViewportClient > (VictoryPlayer->ViewportClient);
                  
              if (!VictoryViewportClient) return false;
              //~~~~~~~~~~~~~~~~~~~~
               
              FViewport * VictoryViewport = VictoryViewportClient->Viewport;
              
              if (!VictoryViewport) return false;
              //~~~~~~~~~~~~~~~~~~~~
              
              PosX = float(VictoryViewport->GetMouseX());
              PosY = float(VictoryViewport->GetMouseY());
              
              return true;
          }
          
          
          
          
          
          
          
          
          
          
          bool UVictoryBPFunctionLibrary::Physics__EnterRagDoll(AActor * TheCharacter)
          {
              ACharacter * AsCharacter = Cast<ACharacter>(TheCharacter);
              if (!AsCharacter) return false;
              
              //Mesh?
              if (!AsCharacter->Mesh) return false;
              
              //Physics Asset?
              if(!AsCharacter->Mesh->GetPhysicsAsset()) return false;
              
              //Victory Ragdoll
              AsCharacter->Mesh->SetPhysicsBlendWeight(1);
              AsCharacter->Mesh->bBlendPhysics = true;
              
              return true;
          }
          
          
          
          
          bool UVictoryBPFunctionLibrary::Physics__LeaveRagDoll(
              AActor* TheCharacter,
              float HeightAboveRBMesh,
              const FVector& InitLocation, 
              const FRotator& InitRotation
          ){
              ACharacter * AsCharacter = Cast<ACharacter>(TheCharacter);
              if (!AsCharacter) return false;
              
              //Mesh?
              if (!AsCharacter->Mesh) return false;
              
              //Set Actor Location to Be Near Ragdolled Mesh
              //Calc Ref Bone Relative Pos for use with IsRagdoll
              TArray<FName> BoneNames;
              AsCharacter->Mesh->GetBoneNames(BoneNames);
              if(BoneNames.Num() > 0)
              {
                  AsCharacter->SetActorLocation(FVector(0,0,HeightAboveRBMesh) + AsCharacter->Mesh->GetBoneLocation(BoneNames[0]));
              }
              
              //Exit Ragdoll
              AsCharacter->Mesh->SetPhysicsBlendWeight(0); //1 for full physics
          
          
              //Restore Defaults
              AsCharacter->Mesh->SetRelativeRotation(InitRotation);
              AsCharacter->Mesh->SetRelativeLocation(InitLocation);
              
              //Set Falling After Final Capsule Relocation
              if(AsCharacter->CharacterMovement) AsCharacter->CharacterMovement->SetMovementMode(MOVE_Falling);    
              
              return true;
          }    
          
          
          bool UVictoryBPFunctionLibrary::Physics__IsRagDoll(AActor* TheCharacter)
          {
              ACharacter * AsCharacter = Cast<ACharacter>(TheCharacter);
              if (!AsCharacter) return false;
              
              //Mesh?
              if (!AsCharacter->Mesh) return false;
              
              return AsCharacter->Mesh->IsAnySimulatingPhysics();
          }    
          
          
          bool UVictoryBPFunctionLibrary::Physics__GetLocationofRagDoll(AActor* TheCharacter, FVector& RagdollLocation)
          {
              ACharacter * AsCharacter = Cast<ACharacter>(TheCharacter);
              if (!AsCharacter) return false;
              
              //Mesh?
              if (!AsCharacter->Mesh) return false;
              
              TArray<FName> BoneNames;
              AsCharacter->Mesh->GetBoneNames(BoneNames);
              if(BoneNames.Num() > 0)
              {
                  RagdollLocation = AsCharacter->Mesh->GetBoneLocation(BoneNames[0]);
              }
              else return false;
              
              return true;
          }
          
          
          bool UVictoryBPFunctionLibrary::Physics__InitializeVictoryRagDoll(
              AActor* TheCharacter, 
              FVector& InitLocation, 
              FRotator& InitRotation
          ){
              ACharacter * AsCharacter = Cast<ACharacter>(TheCharacter);
              if (!AsCharacter) return false;
              
              //Mesh?
              if (!AsCharacter->Mesh) return false;
              
              InitLocation = AsCharacter->Mesh->GetRelativeTransform().GetLocation();
              InitRotation = AsCharacter->Mesh->GetRelativeTransform().Rotator();
              
              return true;
          }
          
          
          bool UVictoryBPFunctionLibrary::Physics__UpdateCharacterCameraToRagdollLocation(
              AActor* TheCharacter, 
              float HeightOffset,
              float InterpSpeed
          ){
              ACharacter * AsCharacter = Cast<ACharacter>(TheCharacter);
              if (!AsCharacter) return false;
              
              //Mesh?
              if (!AsCharacter->Mesh) return false;
              
              //Ragdoll?
              if(!AsCharacter->Mesh->IsAnySimulatingPhysics()) return false;
              
              FVector RagdollLocation = FVector(0,0,0);
              TArray<FName> BoneNames;
              AsCharacter->Mesh->GetBoneNames(BoneNames);
              if(BoneNames.Num() > 0)
              {
                  RagdollLocation = AsCharacter->Mesh->GetBoneLocation(BoneNames[0]);
              }
              
              //Interp
              RagdollLocation = FMath::VInterpTo(AsCharacter->GetActorLocation(), RagdollLocation + FVector(0,0,HeightOffset), AsCharacter->GetWorld()->DeltaTimeSeconds, InterpSpeed);
          
          
              //Set Loc
              AsCharacter->SetActorLocation(RagdollLocation);
              
              return true;
          }
          /*
          bool UVictoryBPFunctionLibrary::Accessor__GetSocketLocalTransform(const USkeletalMeshComponent* Mesh, FTransform& LocalTransform, FName SocketName)
          {
              if(!Mesh) return false;
              
              LocalTransform =  Mesh->GetSocketLocalTransform(SocketName);
              
              return true;
          }
          */
          
          
          void UVictoryBPFunctionLibrary::StringConversion__GetFloatAsStringWithPrecision(float TheFloat, FString & FloatString, uint8 Precision)
          {
              const TCHAR* TheDot = TEXT(".");
                  
              FloatString = FString::SanitizeFloat(TheFloat);
              
              //No . ?
              if( ! FloatString.Contains(TheDot))
              {
                  return;
              }
              
              //Split
              FString LeftS;
              FString RightS;
              
              FloatString.Split(TheDot,&LeftS,&RightS);
              
              //Add dot back to LeftS
              LeftS += TheDot;
              
              //Get the Single Number after the precision amount
              // so in .1273, get the 7
              FString RightSFirstTruncated = "";
              if(RightS.Len() - 1 >= Precision)
              {
                  RightSFirstTruncated = RightS.Mid(Precision,1);
              }
              
              //Truncate the RightS
              //     .1273 becomes .12 with precision 2
              RightS = RightS.Left(Precision);
              
              //Round Up if There was any truncated portion
              if(RightSFirstTruncated != "")
              {
                  if(FCString::Atod(*RightSFirstTruncated) >= 5)
                  {
                      //.1273 becomes .13
                      RightS = FString::FromInt(FCString::Atod(*RightS) + 1);
                  }
              }
              
              FloatString = LeftS + RightS;
          }
          
          
          bool UVictoryBPFunctionLibrary::LensFlare__GetLensFlareOffsets(
              APlayerController* PlayerController,
              AActor* LightSource, 
              float& PitchOffset, 
              float& YawOffset, 
              float& RollOffset
          ){
              if(!PlayerController) return false;
              if(!LightSource) return false;
              //~~~~~~~~~~~~~~~~~~~
              
              //angle from player to light source
              const FRotator AngleToLightSource = (LightSource->GetActorLocation() - PlayerController->GetFocalLocation()).Rotation();
              
              const FRotator Offsets = AngleToLightSource - PlayerController->GetControlRotation();
              
              PitchOffset = Offsets.Pitch;
              YawOffset = Offsets.Yaw;
              RollOffset = Offsets.Roll;
              return true;
          }
          
          
          /*
          bool UVictoryBPFunctionLibrary::AnimatedVertex__GetAnimatedVertexLocations(
              USkeletalMeshComponent* Mesh, 
              TArray<FVector>& Locations
          )
          {
              if(!Mesh) return false;
              if(!Mesh->SkeletalMesh) return false;
              //~~~~~~~~~
              
              Locations.Empty(); 
              //~~~~~~~~~~~~~~~~~~~
              
              //    Get the Verticies For Each Bone, Most Influenced by That Bone!
              //                    Vertices are in Bone space.
              TArray<FBoneVertInfo> BoneVertexInfos;
              FSkeletalMeshTools::CalcBoneVertInfos(Mesh->SkeletalMesh,BoneVertexInfos,true); //true = only dominant influence
              
              //~~~~~~~~~~~~~~~~~~~~~
              int32 VertItr = 0;
              FBoneVertInfo* EachBoneVertInfo;
              FVector BoneWorldPos;
              int32 NumOfVerticies;
              FTransform RV_Transform;
              FVector RV_Vect;
              for(int32 Itr=0; Itr < BoneVertexInfos.Num() ; Itr++)
              {
                  EachBoneVertInfo = &BoneVertexInfos[Itr];
                  //~~~~~~~~~~~~~~~~~~~~~~~~
                  
                  //Bone Transform To World Space, and Location
                  RV_Transform = Mesh->GetBoneTransform(Itr);
                  BoneWorldPos = RV_Transform.GetLocation();
                  
                  //How many verts is this bone influencing?
                  NumOfVerticies = EachBoneVertInfo->Positions.Num();
                  for(VertItr=0; VertItr < NumOfVerticies ; VertItr++)
                  {
                      //Animated Vertex Location!
                      Locations.Add(  BoneWorldPos + RV_Transform.TransformVector(EachBoneVertInfo->Positions[VertItr])  );
                  }
              }
              
              //~~~ Cleanup ~~~
              BoneVertexInfos.Empty();
              
              return true;
          }
              
          bool UVictoryBPFunctionLibrary::AnimatedVertex__GetAnimatedVertexLocationsAndNormals(
              USkeletalMeshComponent* Mesh, 
              TArray<FVector>& Locations, 
              TArray<FVector>& Normals 
          )
          {
              if(!Mesh) return false;
              if(!Mesh->SkeletalMesh) return false;
              //~~~~~~~~~
              
              Locations.Empty(); 
              Normals.Empty();
              //~~~~~~~~~~~~~~~~~~~
              
              //    Get the Verticies For Each Bone, Most Influenced by That Bone!
              //                    Vertices are in Bone space.
              TArray<FBoneVertInfo> BoneVertexInfos;
              FSkeletalMeshTools::CalcBoneVertInfos(Mesh->SkeletalMesh,BoneVertexInfos,true); //true = only dominant influence
              
              //~~~~~~~~~~~~~~~~~~~~~
              int32 VertItr = 0;
              FBoneVertInfo* EachBoneVertInfo;
              FVector BoneWorldPos;
              int32 NumOfVerticies;
              FTransform RV_Transform;
              FVector RV_Vect;
              for(int32 Itr=0; Itr < BoneVertexInfos.Num() ; Itr++)
              {
                  EachBoneVertInfo = &BoneVertexInfos[Itr];
                  //~~~~~~~~~~~~~~~~~~~~~~~~
                  
                  //Bone Transform To World Space, and Location
                  RV_Transform = Mesh->GetBoneTransform(Itr);
                  BoneWorldPos = RV_Transform.GetLocation();
                  
                  //How many verts is this bone influencing?
                  NumOfVerticies = EachBoneVertInfo->Positions.Num();
                  for(VertItr=0; VertItr < NumOfVerticies ; VertItr++)
                  {
                      //Animated Vertex Location!
                      Locations.Add(  BoneWorldPos + RV_Transform.TransformVector(EachBoneVertInfo->Positions[VertItr])  );
                  
                      //Animated Vertex Normal for rotating the emitter!!!!!
                      Normals.Add(  RV_Transform.TransformVector(EachBoneVertInfo->Normals[VertItr])  );
                  }
              }
              
              //~~~ Cleanup ~~~
              BoneVertexInfos.Empty();
              
              return true;
          }
              
          bool UVictoryBPFunctionLibrary::AnimatedVertex__DrawAnimatedVertexLocations(
              UObject* WorldContextObject,
              USkeletalMeshComponent* Mesh, 
              float ChanceToSkipAVertex, 
              bool DrawNormals
          )
          {
              UWorld* const TheWorld = GEngine->GetWorldFromContextObject(WorldContextObject);
              
              if(!TheWorld) return false;
              if(!Mesh) return false;
              if(!Mesh->SkeletalMesh) return false;
              //~~~~~~~~~
              
              //    Get the Verticies For Each Bone, Most Influenced by That Bone!
              //                    Vertices are in Bone space.
              TArray<FBoneVertInfo> BoneVertexInfos;
              FSkeletalMeshTools::CalcBoneVertInfos(Mesh->SkeletalMesh,BoneVertexInfos,true); //true = only dominant influence
              
              //~~~~~~~~~~~~~~~~~~~~~
              int32 VertItr = 0;
              FBoneVertInfo* EachBoneVertInfo;
              FVector BoneWorldPos;
              int32 NumOfVerticies;
              FTransform RV_Transform;
              FVector RV_Vect;
              
              const FColor HappyRed = FColor(255,0,0);
              const FColor HappyBlue = FColor(0,0,255);
              for(int32 Itr=0; Itr < BoneVertexInfos.Num() ; Itr++)
              {
                  EachBoneVertInfo = &BoneVertexInfos[Itr];
                  //~~~~~~~~~~~~~~~~~~~~~~~~
                  
                  //Bone Transform To World Space, and Location
                  RV_Transform = Mesh->GetBoneTransform(Itr);
                  BoneWorldPos = RV_Transform.GetLocation();
                  
                  //How many verts is this bone influencing?
                  NumOfVerticies = EachBoneVertInfo->Positions.Num();
                  for(VertItr=0; VertItr < NumOfVerticies ; VertItr++)
                  {
                      if(FMath::FRandRange(0, 1) < ChanceToSkipAVertex) continue;
                      //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                      
                      RV_Vect = BoneWorldPos + RV_Transform.TransformVector(EachBoneVertInfo->Positions[VertItr]);
                      
                      DrawDebugPoint(
                          TheWorld, 
                          RV_Vect,
                          12, 
                          HappyRed, 
                          false, 
                          0.03
                      );
                      
                      if(DrawNormals)
                      {
                      DrawDebugLine(
                          TheWorld, 
                          RV_Vect, 
                          RV_Vect + RV_Transform.TransformVector(EachBoneVertInfo->Normals[VertItr] * 64),  
                          HappyBlue, 
                          false, 
                          0.03, 
                          0, 
                          1
                      );
                      }
                  }
              }
              
              //~~~ Cleanup ~~~
              BoneVertexInfos.Empty();
              
              return true;
          }
              
          bool UVictoryBPFunctionLibrary::AnimatedVertex__GetCharacterAnimatedVertexLocations(
              AActor* TheCharacter, 
              TArray<FVector>& Locations
          )
          {
              ACharacter * AsCharacter = Cast<ACharacter>(TheCharacter);
              if (!AsCharacter) return false;
              
              USkeletalMeshComponent* Mesh = AsCharacter->Mesh;
              if (!Mesh) return false;
              //~~~~~~~~~~~~~~~~~~~~
              
              AnimatedVertex__GetAnimatedVertexLocations(Mesh,Locations);
              
              return true;
          }
              
          bool UVictoryBPFunctionLibrary::AnimatedVertex__GetCharacterAnimatedVertexLocationsAndNormals(
              AActor* TheCharacter, 
              TArray<FVector>& Locations, 
              TArray<FVector>& Normals 
          )
          {
              ACharacter * AsCharacter = Cast<ACharacter>(TheCharacter);
              if (!AsCharacter) return false;
              
              USkeletalMeshComponent* Mesh = AsCharacter->Mesh;
              if (!Mesh) return false;
              //~~~~~~~~~~~~~~~~~~~~
              
              AnimatedVertex__GetAnimatedVertexLocationsAndNormals(Mesh,Locations,Normals);
              
              return true;
          }
              
          bool UVictoryBPFunctionLibrary::AnimatedVertex__DrawCharacterAnimatedVertexLocations(
              AActor* TheCharacter, 
              float ChanceToSkipAVertex, 
              bool DrawNormals
          )
          {    
              ACharacter * AsCharacter = Cast<ACharacter>(TheCharacter);
              if (!AsCharacter) return false;
              
              USkeletalMeshComponent* Mesh = AsCharacter->Mesh;
              if (!Mesh) return false;
              //~~~~~~~~~~~~~~~~~~~~
              
              AnimatedVertex__DrawAnimatedVertexLocations(TheCharacter,Mesh,ChanceToSkipAVertex,DrawNormals);
              
              return true;
          }
          */
          
          
          //SMA Version
          float UVictoryBPFunctionLibrary::DistanceToSurface__DistaceOfPointToMeshSurface(AStaticMeshActor* TheSMA, const FVector& TestPoint, FVector& ClosestSurfacePoint)
          {
              if(!TheSMA) return -1;
              if(!TheSMA->StaticMeshComponent) return -1;
              //~~~~~~~~~~
              
              //Dist of pt to Surface, retrieve closest Surface Point to Actor
              return TheSMA->StaticMeshComponent->GetDistanceToCollision(TestPoint, ClosestSurfacePoint);
          }
          
          
          bool UVictoryBPFunctionLibrary::Mobility__SetSceneCompMobility(
              USceneComponent* SceneComp,
              EComponentMobility::Type NewMobility
          )
          {
              if(!SceneComp) return false;
              //~~~~~~~~~~~
              
              SceneComp->SetMobility(NewMobility);
              
              return true;
          }
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          //~~~~~~~~~~~~~~~~~~
          //        FullScreen
          //~~~~~~~~~~~~~~~~~~    
          TEnumAsByte<EJoyGraphicsFullScreen::Type> UVictoryBPFunctionLibrary::JoyGraphicsSettings__FullScreen_Get()
          {
              return TEnumAsByte<EJoyGraphicsFullScreen::Type>(JoyGraphics_FullScreen_GetFullScreenType());
          }
                
          void UVictoryBPFunctionLibrary::JoyGraphicsSettings__FullScreen_Set(TEnumAsByte<EJoyGraphicsFullScreen::Type> NewSetting)
          {  
              JoyGraphics_FullScreen_SetFullScreenType(NewSetting.GetValue()); 
          }
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          //~~~~~~~~~~~~~~~~~~~~~~~~~~~
          //~~~~~~~~~~~~~~~~~~~~~~~~~~~
          //~~~~~~~~~~~~~~~~~~~~~~~~~~~
          //              Contributed by Others
          
          
              /**
              * Contributed by: SaxonRah
              * Better random numbers. Seeded with a random device. if the random device's entropy is 0; defaults to current time for seed.
              * can override with seed functions;
              */
          //----------------------------------------------------------------------------------------------BeginRANDOM
              std::random_device rd;        
              unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
          
          
              std::mt19937 rand_MT;
              std::default_random_engine rand_DRE;
          
          
              /** Construct a random device and set seed for engines dependent on entropy */
              void UVictoryBPFunctionLibrary::constructRand()
              {
                  seed = std::chrono::system_clock::now().time_since_epoch().count();
          
          
                  if (rd.entropy() == 0)
                  {
                      seedRand(seed);
                  }else{
                      seedRand(rd());
                  }
              }
              /** Set seed for Rand */
              void UVictoryBPFunctionLibrary::seedRand(int32 _seed)
              {
                  seed = _seed;
              }
          
          
              /** Set seed with time for Rand */
              void UVictoryBPFunctionLibrary::seedRandWithTime()
              {
                  seed = std::chrono::system_clock::now().time_since_epoch().count();
              }
          
          
              /** Set seed with entropy for Rand */
              void UVictoryBPFunctionLibrary::seedRandWithEntropy()
              {
                  seedRand(rd());
              }
          
          
              /** Random Bool - Bernoulli distribution */
              bool UVictoryBPFunctionLibrary::RandBool_Bernoulli(float fBias)
              {
                  std::bernoulli_distribution dis(fBias);
                  return dis(rand_DRE);
              }
          
          
              /** Random Integer - Uniform distribution */
              int32 UVictoryBPFunctionLibrary::RandInt_uniDis()
              {
                  std::uniform_int_distribution<int32> dis(0, 1);
                  return dis(rand_DRE);
              }
              /** Random Integer - Uniform distribution */
              int32 UVictoryBPFunctionLibrary::RandInt_MINMAX_uniDis(int32 iMin, int32 iMax)
              {
                  std::uniform_int_distribution<int32> dis(iMin, iMax);
                  return dis(rand_DRE);
              }
          
          
              /** Random Float - Zero to One Uniform distribution */
              float UVictoryBPFunctionLibrary::RandFloat_uniDis()
              {
                  std::uniform_real_distribution<float> dis(0, 1);
                  return dis(rand_DRE);
              }
              /** Random Float - MIN to MAX Uniform distribution */
              float UVictoryBPFunctionLibrary::RandFloat_MINMAX_uniDis(float iMin, float iMax)
              {
                  std::uniform_real_distribution<float> dis(iMin, iMax);
                  return dis(rand_DRE);
              }
          
          
              /** Random Bool - Bernoulli distribution  -  Mersenne Twister */
              bool UVictoryBPFunctionLibrary::RandBool_Bernoulli_MT(float fBias)
              {
                  std::bernoulli_distribution dis(fBias);
                  return dis(rand_MT);
              }
          
          
              /** Random Integer - Uniform distribution  -  Mersenne Twister */
              int32 UVictoryBPFunctionLibrary::RandInt_uniDis_MT()
              {
                  std::uniform_int_distribution<int32> dis(0, 1);
                  return dis(rand_MT);
              }
              /** Random Integer - Uniform distribution  -  Mersenne Twister */
              int32 UVictoryBPFunctionLibrary::RandInt_MINMAX_uniDis_MT(int32 iMin, int32 iMax)
              {
                  std::uniform_int_distribution<int32> dis(iMin, iMax);
                  return dis(rand_MT);
              }
          
          
              /** Random Float - Zero to One Uniform distribution  -  Mersenne Twister */
              float UVictoryBPFunctionLibrary::RandFloat_uniDis_MT()
              {
                  std::uniform_real_distribution<float> dis(0, 1);
                  return dis(rand_MT);
              }
              /** Random Float - MIN to MAX Uniform distribution  -  Mersenne Twister */
              float UVictoryBPFunctionLibrary::RandFloat_MINMAX_uniDis_MT(float iMin, float iMax)
              {
                  std::uniform_real_distribution<float> dis(iMin, iMax);
                  return dis(rand_MT);
              }
          //----------------------------------------------------------------------------------------------ENDRANDOM
          
          
          
          
          
          
          void UVictoryBPFunctionLibrary::String__ExplodeString(TArray<FString>& OutputStrings, FString InputString, FString Separator, int32 limit, bool bTrimElements)
          {
              OutputStrings.Empty();
              //~~~~~~~~~~~
              
              if (InputString.Len() > 0 && Separator.Len() > 0) {
                  int32 StringIndex = 0;
                  int32 SeparatorIndex = 0;
          
          
                  FString Section = "";
                  FString Extra = "";
          
          
                  int32 PartialMatchStart = -1;
          
          
                  while (StringIndex < InputString.Len()) {
          
          
                      if (InputString[StringIndex] == Separator[SeparatorIndex]) {
                          if (SeparatorIndex == 0) {
                              //A new partial match has started.
                              PartialMatchStart = StringIndex;
                          }
                          Extra.AppendChar(InputString[StringIndex]);
                          if (SeparatorIndex == (Separator.Len() - 1)) {
                              //We have matched the entire separator.
                              SeparatorIndex = 0;
                              PartialMatchStart = -1;
                              if (bTrimElements == true) {
                                  OutputStrings.Add(FString(Section).Trim().TrimTrailing());
                              }
                              else {
                                  OutputStrings.Add(FString(Section));
                              }
          
          
                              //if we have reached the limit, stop.
                              if (limit > 0 && OutputStrings.Num() >= limit) 
                              {
                                  return;
                                  //~~~~
                              }
          
          
                              Extra.Empty();
                              Section.Empty();
                          }
                          else {
                              ++SeparatorIndex;
                          }
                      }
                      else {
                          //Not matched.
                          //We should revert back to PartialMatchStart+1 (if there was a partial match) and clear away extra.
                          if (PartialMatchStart >= 0) {
                              StringIndex = PartialMatchStart;
                              PartialMatchStart = -1;
                              Extra.Empty();
                              SeparatorIndex = 0;
                          }
                          Section.AppendChar(InputString[StringIndex]);
                      }
          
          
                      ++StringIndex;
                  }
          
          
                  //If there is anything left in Section or Extra. They should be added as a new entry.
                  if (bTrimElements == true) {
                      OutputStrings.Add(FString(Section + Extra).Trim().TrimTrailing());
                  }
                  else {
                      OutputStrings.Add(FString(Section + Extra));
                  }
          
          
                  Section.Empty();
                  Extra.Empty();
              }
          }
          
          
          UTexture2D* UVictoryBPFunctionLibrary::GetTexture2DFromFile(const FString& FilePath)
          {
              UTexture2D* Texture = NULL;
          
          
              FString TexturePath = FilePath;//FPaths::GameContentDir( ) + TEXT( "../Data/" ) + TextureFilename;
              TArray<uint8> FileData;
          
          
              /* Load DDS texture */
              if( FFileHelper::LoadFileToArray( FileData, *TexturePath, 0 ) )
              {
                  FDDSLoadHelper DDSLoadHelper( &FileData[ 0 ], FileData.Num( ) );
                  if( DDSLoadHelper.IsValid2DTexture( ) )
                  {
                      int32 NumMips = DDSLoadHelper.ComputeMipMapCount( );
                      EPixelFormat Format = DDSLoadHelper.ComputePixelFormat( );
                      int32 BlockSize = 16;
          
          
                      if( NumMips == 0 )
                      {
                          NumMips = 1;
                      }
          
          
                      if( Format == PF_DXT1 )
                      {
                          BlockSize = 8;
                      }
          
          
                      /* Create transient texture */
                      Texture = UTexture2D::CreateTransient( DDSLoadHelper.DDSHeader->dwWidth, DDSLoadHelper.DDSHeader->dwHeight, Format );
                      
                      #if WITH_EDITOR
                      Texture->MipGenSettings = TMGS_LeaveExistingMips;
                      #endif  //WITH_EDITOR
                      
                      Texture->PlatformData->NumSlices = 1;
                      Texture->NeverStream = true;
                      //Texture->Rename(  );
          
          
                      /* Get pointer to actual data */
                      uint8* DataPtr = (uint8*) DDSLoadHelper.GetDDSDataPointer( );
          
          
                      uint32 CurrentWidth = DDSLoadHelper.DDSHeader->dwWidth;
                      uint32 CurrentHeight = DDSLoadHelper.DDSHeader->dwHeight;
          
          
                      /* Iterate through mips */
                      for( int32 i = 0; i < NumMips; i++ )
                      {
                          /* Lock to 1x1 as smallest size */
                          CurrentWidth = ( CurrentWidth < 1 ) ? 1 : CurrentWidth;
                          CurrentHeight = ( CurrentHeight < 1 ) ? 1 : CurrentHeight;
          
          
                          /* Get number of bytes to read */
                          int32 NumBytes = CurrentWidth * CurrentHeight * 4;
                          if( Format == PF_DXT1 || Format == PF_DXT3 || Format == PF_DXT5 )
                          {
                              /* Compressed formats */
                              NumBytes = ( ( CurrentWidth + 3 ) / 4 ) * ( ( CurrentHeight + 3 ) / 4 ) * BlockSize;
                          }
          
          
                          /* Write to existing mip */
                          if( i < Texture->PlatformData->Mips.Num( ) )
                          {
                              FTexture2DMipMap& Mip = Texture->PlatformData->Mips[ i ];
          
          
                              void* Data = Mip.BulkData.Lock( LOCK_READ_WRITE );
                              FMemory::Memcpy( Data, DataPtr, NumBytes );
                              Mip.BulkData.Unlock( );
                          }
          
          
                          /* Add new mip */
                          else
                          {
                              FTexture2DMipMap* Mip = new( Texture->PlatformData->Mips ) FTexture2DMipMap( );
                              Mip->SizeX = CurrentWidth;
                              Mip->SizeY = CurrentHeight;
          
          
                              Mip->BulkData.Lock( LOCK_READ_WRITE );
                              Mip->BulkData.Realloc( NumBytes );
                              Mip->BulkData.Unlock( );
          
          
                              void* Data = Mip->BulkData.Lock( LOCK_READ_WRITE );
                              FMemory::Memcpy( Data, DataPtr, NumBytes );
                              Mip->BulkData.Unlock( );
                          }
          
          
                          /* Set next mip level */
                          CurrentWidth /= 2;
                          CurrentHeight /= 2;
          
          
                          DataPtr += NumBytes;
                      }
          
          
                      Texture->UpdateResource( );
                  }
              }
          
          
              return Texture;
          }
          
          
          class UAudioComponent* UVictoryBPFunctionLibrary::PlaySoundAttachedFromFile(const FString& FilePath, class USceneComponent* AttachToComponent, FName AttachPointName, FVector Location, EAttachLocation::Type LocationType, bool bStopWhenAttachedToDestroyed, float VolumeMultiplier, float PitchMultiplier, float StartTime, class USoundAttenuation* AttenuationSettings)
          {    
              USoundWave* sw = GetSoundWaveFromFile(FilePath);
          
          
              if (!sw)
                  return NULL;
          
          
              return UGameplayStatics::PlaySoundAttached(sw, AttachToComponent, AttachPointName, Location, LocationType, bStopWhenAttachedToDestroyed, VolumeMultiplier, PitchMultiplier, StartTime, AttenuationSettings);
          }
          
          
          void UVictoryBPFunctionLibrary::PlaySoundAtLocationFromFile(UObject* WorldContextObject, const FString& FilePath, FVector Location, float VolumeMultiplier, float PitchMultiplier, float StartTime, class USoundAttenuation* AttenuationSettings)
          {
              USoundWave* sw = GetSoundWaveFromFile(FilePath);
          
          
              if (!sw)
                  return;
          
          
              UGameplayStatics::PlaySoundAtLocation(WorldContextObject, sw, Location, VolumeMultiplier, PitchMultiplier, StartTime, AttenuationSettings);
          }
          
          
          class USoundWave* UVictoryBPFunctionLibrary::GetSoundWaveFromFile(const FString& FilePath)
          {
              USoundWave* sw = (USoundWave*)StaticConstructObject(USoundWave::StaticClass());
          
          
              if (!sw)
                  return NULL;
          
          
              //* If true the song was successfully loaded
              bool loaded = false;
          
          
              //* loaded song file (binary, encoded)
              TArray < uint8 > rawFile;
          
          
              loaded = FFileHelper::LoadFileToArray(rawFile, FilePath.GetCharArray().GetData());
          
          
              if (loaded)
              {
                  FByteBulkData* bulkData = &sw->CompressedFormatData.GetFormat(TEXT("OGG"));
          
          
                  bulkData->Lock(LOCK_READ_WRITE);
                  FMemory::Memcpy(bulkData->Realloc(rawFile.Num()), rawFile.GetData(), rawFile.Num());
                  bulkData->Unlock();
          
          
                  loaded = fillSoundWaveInfo(sw, &rawFile) == 0 ? true : false;
              }
          
          
              if (!loaded)
                  return NULL;
          
          
              return sw;
          }
          
          
          int32 UVictoryBPFunctionLibrary::fillSoundWaveInfo(class USoundWave* sw, TArray<uint8>* rawFile)
          {
              FSoundQualityInfo info;
              FVorbisAudioInfo vorbis_obj = FVorbisAudioInfo();
              if (!vorbis_obj.ReadCompressedInfo(rawFile->GetData(), rawFile->Num(), &info))
              {
                  //Debug("Can't load header");
                  return 1;
              }
          
          
              if(!sw) return 1;
              sw->SoundGroup = ESoundGroup::SOUNDGROUP_Default;
              sw->NumChannels = info.NumChannels;
              sw->Duration = info.Duration;
              sw->RawPCMDataSize = info.SampleDataSize;
              sw->SampleRate = info.SampleRate;
          
          
              return 0;
          }
          
          
                
          int32 UVictoryBPFunctionLibrary::findSource(class USoundWave* sw, class FSoundSource* out_audioSource)
          {
              FAudioDevice* device = GEngine ? GEngine->GetAudioDevice() : NULL; //gently ask for the audio device
          
          
              FActiveSound* activeSound;
              FSoundSource* audioSource;
              FWaveInstance* sw_instance;
              if (!device)
              {
                  activeSound = NULL;
                  audioSource = NULL;
                  out_audioSource = audioSource;
                  return -1;
              }
          
          
              TArray<FActiveSound*> tmpActualSounds = device->GetActiveSounds();
              if (tmpActualSounds.Num())
              {
                  for (auto activeSoundIt(tmpActualSounds.CreateIterator()); activeSoundIt; ++activeSoundIt)
                  {
                      activeSound = *activeSoundIt;
                      for (auto WaveInstanceIt(activeSound->WaveInstances.CreateIterator()); WaveInstanceIt; ++WaveInstanceIt)
                      {
                          sw_instance = WaveInstanceIt.Value();
                          if (sw_instance->WaveData->CompressedDataGuid == sw->CompressedDataGuid)
                          {
                              audioSource = device->WaveInstanceSourceMap.FindRef(sw_instance);
                              out_audioSource = audioSource;
                              return 0;
                          }
                      }
                  }
              }
          
          
              audioSource = NULL;
              activeSound = NULL;
              out_audioSource = audioSource;
              return -2;
          }
          
          
          
          
          //TESTING
          static void TESTINGInternalDrawDebugCircle(const UWorld* InWorld, const FMatrix& TransformMatrix, float Radius, int32 Segments, const FColor& Color, bool bPersistentLines, float LifeTime, uint8 DepthPriority, float Thickness=0)
          {
              //this is how you can make cpp only internal functions!
              
          }
          Attached Files
          Last edited by SaxonRah; 12-17-2014, 03:28 AM.
          Youtube
          Machine Learning C++ Plugin
          Lindenmayer System C++ Plugin

          Comment


            Originally posted by Rama View Post
            Can you give me the whole crash log?

            Do you mean using ?listen or as dedicated server?

            Please load the editor / run the game from commandline with -log and send me the whole log after verifying the date and time at the top of the log as being your must recent test.

            I run games as a listen server all the time without any issues with the plugin

            So I need more info!

            Rama
            I know it's been a while, but here's the info:

            I've been running it as a dedicated server, and this issue resurfaced recently when I just tried to implement your GetAllWidgetsOfClass and RemoveAllWidgetsOfClass methods. If I have a function library with the method signature "static void testMethod(UObject* WorldContextObject);", there is no error.

            However, "static void testMethodUObject* WorldContextObject, TSubclassOf<UUserWidget> WidgetClass);" crashes on dedicated server. I'm not calling the method anywhere, just declaring it in a method header. I believe the issue is that UUserWidget does not exist in a strictly server context, so it can't resolve what it's a subclass of (hence trying to cast a null to a Blueprint). This would be why it compiles fine and only crashes on server runtime.

            I tried adding "Client" to the UFUNCTION macro, but it gives me an error saying static functions can't be replicated, so no luck there.

            I didn't find the log file particularly helpful (though it is full of UMG errors that might give credence to my theory that a designated server doesn't know what a widget is), and it is extremely large, so I've cut out most of the middle and attached it here.

            I'll keep working on getting it working, but let me know if you need any more info from me!

            EDIT: I tried adding

            virtual bool NeedsLoadForClient() const override
            {
            return false;
            }
            virtual bool NeedsLoadForServer() const override
            {
            return false;
            }


            to the Blueprint Function Library class (as suggested by this AnswerHub question) but that didn't seem to do anything, no matter what combination of true and false I put in the return statements. After I added some debug statements to it, it didn't seem like it was ever calling NeedsLoadForServer/Client from the BlueprintFunctionLibrary.
            Attached Files
            Last edited by rosella500; 12-18-2014, 02:29 PM.

            Comment


              Originally posted by SaxonRah View Post
              Code for you!

              Let me know if you want an actual copy.
              (note: all of my code should be within BeginRandom and EndRandom comments for ctrl-f ability)

              Also you are more than welcome to change anything you see fit. Code is 10000% free

              Wohoo!

              I look forward to integrating this!

              Yes please send me the code by pm

              Rama
              100+ UE4 C++ Tutorials on the UE4 Code Wiki, including UE4 Multi-Threading!

              UE4 Marketplace: Melee Weapon Plugin & Compressed Binary Save System Plugin | Rama's C++ AI Jumping Videos | Vertex Snap Editor Plugin

              Visit www.ue4code.com to see lots of videos about my C++ Creations! ♥ Rama

              Comment


                Click image for larger version

Name:	FindPlayerStart.jpg
Views:	3
Size:	285.1 KB
ID:	1064322

                Rama's Multiplayer Game Mode Solution


                Find Player Start

                Choose Player Start

                Can Player Restart


                These core Multiplayer functions are now fully implementable/overridable in Blueprints!


                I have found a solution for the issue of implementing FindPlayerStart, ChoosePlayerStart, and CanPlayerRestart in Blueprints!

                And I've tested it as working!


                You can now implement core network coding of choosing player starts entirely in Blueprints!


                ~~~

                How To Use

                In my picture below I show how to use my Game Mode overrides!

                1. First make a new BP and select my VictoryGameMode class which comes with my Victory BP Library (make sure you have the latest download https://wiki.unrealengine.com/File:VictoryPlugin.zip)

                If you already have a Game Mode BP, choose File -> Reparent and use my Victory Game Mode BP


                2. Make sure you are using my Victory Game Mode in your World Settings!

                3. Setup the Victory Game Mode BP the same as my picture below!

                4. Celebrate! You can now implement core multiplayer logic in Blueprints!

                (right click -> new tab to see larger pic)
                Click image for larger version

Name:	VictoryGameMode.jpg
Views:	1
Size:	290.1 KB
ID:	1060933

                ~~~

                CPP Override and CPP Override Var

                Please note the notation I am using, any variable that has CPPOverride Var in its name is used only with the corresponding event. This is how I enable you to implement core multiplayer coding logic in Blueprints!

                ~~~

                Simple Data Types

                Please note that for the function that is designed to return a boolean value, CanPlayerRestart, you must pass the boolean and also a special variable, CPPOverride SelfReference, this is how you tell the CPP that you are implementing the Game Mode function in BP!

                ~~~

                Non Destructive Solution

                My solution is entirely optional and if you do not implement the event in Blueprints, and your programmer does it in C++, my solution will not interfere at all with your existing code base!

                ~~~

                Log Message

                If you do implement my solution in BP, I am printing log information to indicate this, so you/your programmer knows you are using a BP override and any C++ code will not be run.

                ~~~

                C++ Code

                Here is my C++ code for FindPlayerStart which shows how I worked around the issue of overriding FindPlayerStart via Blueprints!

                Again I've tested this as entirely working in PIE and commandline games!

                .h
                Code:
                //Find Player Start
                public:
                	/** Use this var inside the body of CPP Override ~ Find Player Start event to override the C++ functionality! */
                	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Victory Game Mode")
                	AActor* CPPOverrideVar_FindPlayerStart;
                	
                	/** 
                	 * Use CPPOverrideVar_FindPlayerStart inside of this event to implement FindPlayerStart in BP ! <3 Rama
                	 *
                	 * Return the 'best' player start for this player to start from.
                	 * @param Player - is the AController for whom we are choosing a playerstart
                	 * @param IncomingName - specifies the tag of a Playerstart to use
                	 * @returns Actor chosen as player start (usually a PlayerStart)
                	 */
                	UFUNCTION(BlueprintImplementableEvent, meta=(FriendlyName = "CPP Override ~ Find Player Start"))
                	virtual void CPPOverride_FindPlayerStart();
                
                	virtual class AActor* FindPlayerStart( AController* Player, const FString& IncomingName = TEXT("") ) override;
                .cpp
                Code:
                //Find
                AActor* AVictoryGameMode::FindPlayerStart( AController* Player, const FString& IncomingName )
                {
                	//Clear any previous to indicate whether BP did an override
                	CPPOverrideVar_FindPlayerStart = NULL;
                	
                	//=======================
                	//BP Hook by Rama
                	this->CPPOverride_FindPlayerStart();
                	//=======================
                	
                	if(CPPOverrideVar_FindPlayerStart) //Did BP programmer set the var?
                	{ 
                		//Indicate that the BP override was found and is being used.
                		UE_LOG(VictoryGameModeLog, Log, TEXT("\n\n"));
                		UE_LOG(VictoryGameModeLog, Log, TEXT("FindPlayerStart: CPP override found in %s and used instead of C++ implementation"), *GetName());
                		UE_LOG(VictoryGameModeLog, Log, TEXT("\n\n"));
                
                		return CPPOverrideVar_FindPlayerStart;
                	} 
                	 
                	//Default C++ Implementation
                	return Super::FindPlayerStart(Player,IncomingName);
                }
                ~~~

                Enjoy!

                Rama
                Last edited by Rama; 12-19-2014, 07:44 PM.
                100+ UE4 C++ Tutorials on the UE4 Code Wiki, including UE4 Multi-Threading!

                UE4 Marketplace: Melee Weapon Plugin & Compressed Binary Save System Plugin | Rama's C++ AI Jumping Videos | Vertex Snap Editor Plugin

                Visit www.ue4code.com to see lots of videos about my C++ Creations! ♥ Rama

                Comment


                  SaxonRah's Super Random BP Nodes For You!

                  Dear Community,

                  Community member SaxonRah has gifted us all with a whole new set of Randomization nodes!

                  Check out these pics!

                  Click image for larger version

Name:	Random.png
Views:	3
Size:	153.6 KB
ID:	1064365

                  Click image for larger version

Name:	Randon3.png
Views:	1
Size:	110.1 KB
ID:	1064489
                  ~~~

                  Latest Version of My Plugin Has The Additions

                  https://wiki.unrealengine.com/File:VictoryPlugin.zip

                  ~~~

                  C++ Code

                  Here is the C++ code for SaxonRah's additions to my Victory BP Library

                  .h
                  Code:
                  /** Seed Rand with value passed
                  * @param seed - value to pass to the prng as the seed
                  */
                  UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Random")
                  static void seedRand(int32 seed);
                  
                  /** Seed Rand with current time
                  */
                  UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Random")
                  static void seedRandWithTime();
                  
                  /** Seed Rand with entropy
                  * @param seed - value to pass to the prng as the seed
                  */
                  UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Random")
                  static void seedRandWithEntropy();
                  
                  /** Random Bool - Bernoulli distribution
                  * @param fBias - Bias of Bernoulli distribution
                  * @return uniformly distributed bool based on bias parameter
                  */
                  UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Random")
                  static bool RandBool_Bernoulli(float fBias);
                  
                  /** Random Integer - Zero to One Uniform distribution
                  * @return int32 - uniform distribution from 0 to 1
                  */
                  UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Random")
                  static int32 RandInt_uniDis();
                  
                  /** Random Integer - MIN to MAX Uniform distribution
                  * @param iMin - Minimum value of uniform distribution
                  * @param iMax - Maximum value of uniform distribution
                  * @return int32 - uniform distribution from iMin to iMax parameters
                  */
                  UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Random")
                  static int32 RandInt_MINMAX_uniDis(int32 iMin, int32 iMax);
                  
                  /** Random Double - Zero to One Uniform distribution
                  * @return double - uniform distribution from 0 to 1
                  */
                  UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Random")
                  static float RandFloat_uniDis();
                  
                  /** Random Double - Uniform distribution based on MIN to MAX parameters
                  * @param iMin - Minimum value of uniform distribution
                  * @param iMax - Maximum value of uniform distribution
                  * @return double - uniform distribution from iMin to iMax parameters
                  */
                  UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Random")
                  static float RandFloat_MINMAX_uniDis(float iMin, float iMax);
                  
                  /** Random Bool - Bernoulli distribution - Mersenne Twister
                  * @param fBias - Bias of Bernoulli distribution
                  * @return uniformly distributed bool based on bias parameter
                  */
                  UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Random")
                  static bool RandBool_Bernoulli_MT(float fBias);
                  
                  /** Random Integer - Zero to One Uniform distribution - Mersenne Twister
                  * @return int32 - uniform distribution from 0 to 1
                  */
                  UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Random")
                  static int32 RandInt_uniDis_MT();
                  
                  /** Random Integer - MIN to MAX Uniform distribution - Mersenne Twister
                  * @param iMin - Minimum value of uniform distribution
                  * @param iMax - Maximum value of uniform distribution
                  * @return int32 - uniform distribution from iMin to iMax parameters
                  */
                  UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Random")
                  static int32 RandInt_MINMAX_uniDis_MT(int32 iMin, int32 iMax);
                  
                  /** Random Float - Zero to One Uniform distribution -  Mersenne Twister
                  * @return float - uniform distribution from 0 to 1
                  */
                  UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Random")
                  static float RandFloat_uniDis_MT();
                  
                  /** Random Float - Uniform distribution based on MIN to MAX parameters - Mersenne Twister
                  * @param iMin - Minimum value of uniform distribution
                  * @param iMax - Maximum value of uniform distribution
                  * @return float - uniform distribution from iMin to iMax parameters
                  */
                  UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Random")
                  static float RandFloat_MINMAX_uniDis_MT(float iMin, float iMax);
                  .cpp
                  Code:
                  /**
                  * Contributed by: SaxonRah
                  * Better random numbers. Seeded with a random device. if the random device's entropy is 0; defaults to current time for seed.
                  * can override with seed functions;
                  */
                  //----------------------------------------------------------------------------------------------BeginRANDOM
                  std::random_device rd;		
                  unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
                  
                  std::mt19937 rand_MT;
                  std::default_random_engine rand_DRE;
                  
                  /** Construct a random device and set seed for engines dependent on entropy */
                  void UVictoryBPFunctionLibrary::constructRand()
                  {
                  	seed = std::chrono::system_clock::now().time_since_epoch().count();
                  
                  	if (rd.entropy() == 0)
                  	{
                  		seedRand(seed);
                  	}else{
                  		seedRand(rd());
                  	}
                  }
                  /** Set seed for Rand */
                  void UVictoryBPFunctionLibrary::seedRand(int32 _seed)
                  {
                  	seed = _seed;
                  }
                  
                  /** Set seed with time for Rand */
                  void UVictoryBPFunctionLibrary::seedRandWithTime()
                  {
                  	seed = std::chrono::system_clock::now().time_since_epoch().count();
                  }
                  
                  /** Set seed with entropy for Rand */
                  void UVictoryBPFunctionLibrary::seedRandWithEntropy()
                  {
                  	seedRand(rd());
                  }
                  
                  /** Random Bool - Bernoulli distribution */
                  bool UVictoryBPFunctionLibrary::RandBool_Bernoulli(float fBias)
                  {
                  	std::bernoulli_distribution dis(fBias);
                  	return dis(rand_DRE);
                  }
                  
                  /** Random Integer - Uniform distribution */
                  int32 UVictoryBPFunctionLibrary::RandInt_uniDis()
                  {
                  	std::uniform_int_distribution<int32> dis(0, 1);
                  	return dis(rand_DRE);
                  }
                  /** Random Integer - Uniform distribution */
                  int32 UVictoryBPFunctionLibrary::RandInt_MINMAX_uniDis(int32 iMin, int32 iMax)
                  {
                  	std::uniform_int_distribution<int32> dis(iMin, iMax);
                  	return dis(rand_DRE);
                  }
                  
                  /** Random Float - Zero to One Uniform distribution */
                  float UVictoryBPFunctionLibrary::RandFloat_uniDis()
                  {
                  	std::uniform_real_distribution<float> dis(0, 1);
                  	return dis(rand_DRE);
                  }
                  /** Random Float - MIN to MAX Uniform distribution */
                  float UVictoryBPFunctionLibrary::RandFloat_MINMAX_uniDis(float iMin, float iMax)
                  {
                  	std::uniform_real_distribution<float> dis(iMin, iMax);
                  	return dis(rand_DRE);
                  }
                  
                  /** Random Bool - Bernoulli distribution  -  Mersenne Twister */
                  bool UVictoryBPFunctionLibrary::RandBool_Bernoulli_MT(float fBias)
                  {
                  	std::bernoulli_distribution dis(fBias);
                  	return dis(rand_MT);
                  }
                  
                  /** Random Integer - Uniform distribution  -  Mersenne Twister */
                  int32 UVictoryBPFunctionLibrary::RandInt_uniDis_MT()
                  {
                  	std::uniform_int_distribution<int32> dis(0, 1);
                  	return dis(rand_MT);
                  }
                  /** Random Integer - Uniform distribution  -  Mersenne Twister */
                  int32 UVictoryBPFunctionLibrary::RandInt_MINMAX_uniDis_MT(int32 iMin, int32 iMax)
                  {
                  	std::uniform_int_distribution<int32> dis(iMin, iMax);
                  	return dis(rand_MT);
                  }
                  
                  /** Random Float - Zero to One Uniform distribution  -  Mersenne Twister */
                  float UVictoryBPFunctionLibrary::RandFloat_uniDis_MT()
                  {
                  	std::uniform_real_distribution<float> dis(0, 1);
                  	return dis(rand_MT);
                  }
                  /** Random Float - MIN to MAX Uniform distribution  -  Mersenne Twister */
                  float UVictoryBPFunctionLibrary::RandFloat_MINMAX_uniDis_MT(float iMin, float iMax)
                  {
                  	std::uniform_real_distribution<float> dis(iMin, iMax);
                  	return dis(rand_MT);
                  }
                  Last edited by Rama; 12-23-2014, 03:25 PM.
                  100+ UE4 C++ Tutorials on the UE4 Code Wiki, including UE4 Multi-Threading!

                  UE4 Marketplace: Melee Weapon Plugin & Compressed Binary Save System Plugin | Rama's C++ AI Jumping Videos | Vertex Snap Editor Plugin

                  Visit www.ue4code.com to see lots of videos about my C++ Creations! ♥ Rama

                  Comment


                    *Drooling* This is so awesome! Thank you SaxonRah and Rama, you guys are great!

                    Comment


                      Originally posted by Dakraid View Post
                      *Drooling* This is so awesome! Thank you SaxonRah and Rama, you guys are great!
                      Hee hee!

                      I hope you enjoy the new advanced Randomization nodes!



                      Rama
                      100+ UE4 C++ Tutorials on the UE4 Code Wiki, including UE4 Multi-Threading!

                      UE4 Marketplace: Melee Weapon Plugin & Compressed Binary Save System Plugin | Rama's C++ AI Jumping Videos | Vertex Snap Editor Plugin

                      Visit www.ue4code.com to see lots of videos about my C++ Creations! ♥ Rama

                      Comment


                        Victory BP Library Holiday Special

                        Dear Community,

                        For Christmas I have a special of the following new additions!

                        Random Number Generator nodes by SaxonRah

                        3 Nodes by Kris

                        2 Nodes by Me


                        ~~~

                        Saxon Rah Super Random Nodes
                        https://forums.unrealengine.com/show...l=1#post195924

                        ~~~

                        Nodes by Kris

                        Kris has offered us an easy way to project the results of a SceneCapture or SceneCaptureComponent2D !

                        This is very useful for making minimaps!

                        Click image for larger version

Name:	Capture2DProject.jpg
Views:	1
Size:	159.3 KB
ID:	1064415




                        C++ Code

                        I thought Kris's project node was particularly neat!

                        Here's the code for it!

                        Code:
                        bool UVictoryBPFunctionLibrary::CaptureComponent2D_Project(class USceneCaptureComponent2D* Target, FVector Location, FVector2D& OutPixelLocation)
                        {
                            if ((Target == nullptr) || (Target->TextureTarget == nullptr))
                            {
                                return false;
                            }
                            
                            const FTransform& Transform = Target->GetComponentToWorld();
                            FMatrix ViewMatrix = Transform.ToInverseMatrixWithScale();
                            FVector ViewLocation = Transform.GetTranslation();
                        
                            // swap axis st. x=z,y=x,z=y (unreal coord space) so that z is up
                            ViewMatrix = ViewMatrix * FMatrix(
                                FPlane(0,    0,    1,    0),
                                FPlane(1,    0,    0,    0),
                                FPlane(0,    1,    0,    0),
                                FPlane(0,    0,    0,    1));
                        
                            const float FOV = Target->FOVAngle * (float)PI / 360.0f;
                        
                            FIntPoint CaptureSize(Target->TextureTarget->GetSurfaceWidth(), Target->TextureTarget->GetSurfaceHeight());
                            
                            float XAxisMultiplier;
                            float YAxisMultiplier;
                        
                            if (CaptureSize.X > CaptureSize.Y)
                            {
                                // if the viewport is wider than it is tall
                                XAxisMultiplier = 1.0f;
                                YAxisMultiplier = CaptureSize.X / (float)CaptureSize.Y;
                            }
                            else
                            {
                                // if the viewport is taller than it is wide
                                XAxisMultiplier = CaptureSize.Y / (float)CaptureSize.X;
                                YAxisMultiplier = 1.0f;
                            }
                        
                            FMatrix    ProjectionMatrix = FReversedZPerspectiveMatrix (
                                FOV,
                                FOV,
                                XAxisMultiplier,
                                YAxisMultiplier,
                                GNearClippingPlane,
                                GNearClippingPlane
                                );
                        
                            FMatrix ViewProjectionMatrix = ViewMatrix * ProjectionMatrix;
                        
                            FVector4 ScreenPoint = ViewProjectionMatrix.TransformFVector4(FVector4(Location,1));
                            
                            if (ScreenPoint.W > 0.0f)
                            {
                                float InvW = 1.0f / ScreenPoint.W;
                                float Y = (GProjectionSignY > 0.0f) ? ScreenPoint.Y : 1.0f - ScreenPoint.Y;
                                FIntRect ViewRect = FIntRect(0, 0, CaptureSize.X, CaptureSize.Y);
                                OutPixelLocation = FVector2D(
                                    ViewRect.Min.X + (0.5f + ScreenPoint.X * 0.5f * InvW) * ViewRect.Width(),
                                    ViewRect.Min.Y + (0.5f - Y * 0.5f * InvW) * ViewRect.Height()
                                    );
                                return true;
                            }
                        
                            return false;
                        }
                        ~~~

                        Get Player Start by Name & Server Travel

                        You can use the Server Travel node to initiate an asynchronous loading process, which enables you to put up a transition effect! You can use UMG and my RemoveAllWidgetsOfClass node to remove the transition effect after the level change completes!

                        You can save a Player start name to disk using my Config Suite, and then find that player start in the new level using GetPlayerStart!

                        Click image for larger version

Name:	GetPlayerStart.jpg
Views:	1
Size:	66.9 KB
ID:	1064416

                        Click image for larger version

Name:	ServerTravel.jpg
Views:	1
Size:	57.1 KB
ID:	1064417

                        Enjoy!

                        Rama
                        Last edited by Rama; 12-24-2014, 12:19 AM.
                        100+ UE4 C++ Tutorials on the UE4 Code Wiki, including UE4 Multi-Threading!

                        UE4 Marketplace: Melee Weapon Plugin & Compressed Binary Save System Plugin | Rama's C++ AI Jumping Videos | Vertex Snap Editor Plugin

                        Visit www.ue4code.com to see lots of videos about my C++ Creations! ♥ Rama

                        Comment


                          Hope that the Scene Capture Project functions & CreateTextureRenderTarget2D function are of use to someone.

                          We've been using CreateTextureRenderTarget2D() for our optical sights and UI related elements for quite some time. It allows us to create texture render targets on the fly and not have to worry about creating them manually in the content browser.

                          We use Project() for rendering attachment points for our character and items in the customisation UI.

                          I created a crappy quick mini-map project that uses it as an example.
                          I'll see about getting it online soon.

                          Kris.
                          Rule#21: Be polite, be professional, but have a plan to kill everyone you meet.

                          Comment


                            Very handy stuff as usual. Thanks Rama and all the contributors!
                            FREE VR Drum Kit Project
                            FREE Color LUT Collection
                            FREE Physics Driven Spacecraft Project
                            FREE GTA Style Vehicle Interaction
                            Dynamic DoF(Depth of Field)
                            Camera Crossfade

                            Comment


                              Originally posted by Jacky View Post
                              Very handy stuff as usual. Thanks Rama and all the contributors!
                              Great to hear from you as always Jacky!

                              ~~~

                              I now got the picture where Kris demonstrates how his SceneCaptureComponent2D projection code works! Full details below!

                              These nodes are in my Victory BP Library already!

                              Nodes by Kris

                              Kris has offered us an easy way to project the results of a SceneCapture or SceneCaptureComponent2D !

                              This is very useful for making minimaps!

                              Click image for larger version

Name:	Capture2DProject.jpg
Views:	1
Size:	159.3 KB
ID:	1064415




                              C++ Code

                              I thought Kris's project node was particularly neat!

                              Here's the code for it!

                              Code:
                              bool UVictoryBPFunctionLibrary::CaptureComponent2D_Project(class USceneCaptureComponent2D* Target, FVector Location, FVector2D& OutPixelLocation)
                              {
                                  if ((Target == nullptr) || (Target->TextureTarget == nullptr))
                                  {
                                      return false;
                                  }
                                  
                                  const FTransform& Transform = Target->GetComponentToWorld();
                                  FMatrix ViewMatrix = Transform.ToInverseMatrixWithScale();
                                  FVector ViewLocation = Transform.GetTranslation();
                              
                                  // swap axis st. x=z,y=x,z=y (unreal coord space) so that z is up
                                  ViewMatrix = ViewMatrix * FMatrix(
                                      FPlane(0,    0,    1,    0),
                                      FPlane(1,    0,    0,    0),
                                      FPlane(0,    1,    0,    0),
                                      FPlane(0,    0,    0,    1));
                              
                                  const float FOV = Target->FOVAngle * (float)PI / 360.0f;
                              
                                  FIntPoint CaptureSize(Target->TextureTarget->GetSurfaceWidth(), Target->TextureTarget->GetSurfaceHeight());
                                  
                                  float XAxisMultiplier;
                                  float YAxisMultiplier;
                              
                                  if (CaptureSize.X > CaptureSize.Y)
                                  {
                                      // if the viewport is wider than it is tall
                                      XAxisMultiplier = 1.0f;
                                      YAxisMultiplier = CaptureSize.X / (float)CaptureSize.Y;
                                  }
                                  else
                                  {
                                      // if the viewport is taller than it is wide
                                      XAxisMultiplier = CaptureSize.Y / (float)CaptureSize.X;
                                      YAxisMultiplier = 1.0f;
                                  }
                              
                                  FMatrix    ProjectionMatrix = FReversedZPerspectiveMatrix (
                                      FOV,
                                      FOV,
                                      XAxisMultiplier,
                                      YAxisMultiplier,
                                      GNearClippingPlane,
                                      GNearClippingPlane
                                      );
                              
                                  FMatrix ViewProjectionMatrix = ViewMatrix * ProjectionMatrix;
                              
                                  FVector4 ScreenPoint = ViewProjectionMatrix.TransformFVector4(FVector4(Location,1));
                                  
                                  if (ScreenPoint.W > 0.0f)
                                  {
                                      float InvW = 1.0f / ScreenPoint.W;
                                      float Y = (GProjectionSignY > 0.0f) ? ScreenPoint.Y : 1.0f - ScreenPoint.Y;
                                      FIntRect ViewRect = FIntRect(0, 0, CaptureSize.X, CaptureSize.Y);
                                      OutPixelLocation = FVector2D(
                                          ViewRect.Min.X + (0.5f + ScreenPoint.X * 0.5f * InvW) * ViewRect.Width(),
                                          ViewRect.Min.Y + (0.5f - Y * 0.5f * InvW) * ViewRect.Height()
                                          );
                                      return true;
                                  }
                              
                                  return false;
                              }
                              100+ UE4 C++ Tutorials on the UE4 Code Wiki, including UE4 Multi-Threading!

                              UE4 Marketplace: Melee Weapon Plugin & Compressed Binary Save System Plugin | Rama's C++ AI Jumping Videos | Vertex Snap Editor Plugin

                              Visit www.ue4code.com to see lots of videos about my C++ Creations! ♥ Rama

                              Comment


                                Holiday Special

                                See the upper 3 posts for my Victory BP Library Holiday Special!

                                Rama
                                100+ UE4 C++ Tutorials on the UE4 Code Wiki, including UE4 Multi-Threading!

                                UE4 Marketplace: Melee Weapon Plugin & Compressed Binary Save System Plugin | Rama's C++ AI Jumping Videos | Vertex Snap Editor Plugin

                                Visit www.ue4code.com to see lots of videos about my C++ Creations! ♥ Rama

                                Comment

                                Working...
                                X