// Fill out your copyright notice in the Description page of Project Settings. #pragma once #include "CoreMinimal.h" #include "Kismet/KismetSystemLibrary.h" #include "Input/Events.h" #include "Common.h" #include "Kismet/BlueprintFunctionLibrary.h" #include "UtilityLibrary.generated.h" class UEnhancedInputLocalPlayerSubsystem; class UAnimSequenceBase; /** * * UlxUtilityLibrary is for functions that are aren't particularly luprex-specific, * but rather, are just generally-useful functionality that could help in any * Unreal program. * */ UCLASS() class INTEGRATION_API UlxUtilityLibrary : public UBlueprintFunctionLibrary { GENERATED_BODY() public: // Call a function by name, on any UObject. If the function doesn't exist, calls // the fallback function instead. If that isn't found either, returns false. // UFUNCTION(BlueprintCallable, Meta = (DefaultToSelf = "target"), Category = "Luprex|Utility") static void CallFunctionByName(UObject *target, const FString &NamePart1, const FString &NamePart2, const FString &fallback, bool bFailIfNotFound = true); // Get the axis-aligned bounding box of an actor. // UFUNCTION(BlueprintCallable, Meta = (DefaultToSelf = "target"), Category = "Luprex|Utility") static FBox GetActorBounds(const AActor *target, bool bOnlyCollidingComponents = false, bool bIncludeFromChildActors = false); // Add movement input, using the yaw of the control rotation to find a rightward vector. // UFUNCTION(BlueprintCallable, Meta = (DefaultToSelf = "target"), Category = "Pawn|Input") static void AddMovementInputRightward(APawn *target, double ScaleValue=1.0, bool Force=false); // Add movement input, using the yaw of the control rotation to find a forward vector. // UFUNCTION(BlueprintCallable, Meta = (DefaultToSelf = "target"), Category = "Pawn|Input") static void AddMovementInputForward(APawn *target, double ScaleValue=1.0, bool Force=false); // Get the enhanced input local player subsystem from a controller. If the controller // is not a player controller, or if it is a player controller but it doesn't have an // enhanced input subsystem, return nullptr. UFUNCTION(BlueprintPure, Category="Player Controller|Local Player Subsystems") static UEnhancedInputLocalPlayerSubsystem *GetEnhancedInputLocalPlayerSubsystem(AController *Controller); // Given a Pixel XY coordinate, convert it to a viewport position. // // The input should be in the range (0.0, 0.0) to (ViewportX, ViewportY). // The output XY will be in the range 0.0 to 1.0. The input // may specify a fraction of a pixel. So the input (0.0, 0.0) // represents the upper-left corner of the upper-left pixel, whereas the // input (0.5, 0.5) represents the center of the upper-left pixel. UFUNCTION(BlueprintPure, meta = (ReturnDisplayName = "Percent XY"), Category="Luprex|Utility") static FVector2D PixelToViewportPosition(FVector2D PixelXY); // Given a viewport position, convert it to a Pixel XY coordinate. // // The input X and Y coordinates should be in the range 0 to 1. The output // will be in the range (0,0) to (ViewportX, ViewportY). The output may // specify a fraction of a pixel. If SnapToCenter is true, the output is // rounded to the center of the nearest pixel. UFUNCTION(BlueprintPure, meta = (ReturnDisplayName = "Pixel XY"), Category="Luprex|Utility") static FVector2D ViewportPositionToPixel(FVector2D PercentXY, bool SnapToCenter); // Do a Line Trace from the camera through a specified pixel. // // This can be used when you have a crosshair on the screen and you want to // determine the object that the crosshairs are pointing at. It can also // be used to do a line trace through the mouse. Fractional pixels are allowed. // Be aware that (0.0, 0.0) is the upper-left corner of the upper-left pixel, // whereas (0.5, 0.5) is the center of the upper-left pixel. // // The resulting TraceStart and TraceEnd fields of the HitResult will not // contain world positions, instead, they will contain the PixelXY. // UFUNCTION(BlueprintCallable, Category="Collision", meta=(AutoCreateRefTerm="ActorsToIgnore", Keywords="raycast")) static bool LineTraceThroughPixel(const APlayerController* PlayerController, FVector2D PixelXY, double MaxDistanceFromCamera, ETraceTypeQuery TraceChannel, bool bTraceComplex, EDrawDebugTrace::Type DrawDebugType, bool bIgnorePlayerPawn, const TArray& ActorsToIgnore, FHitResult& HitResult); // Set Position of GridPanel Middle Cell // // Sometimes, you want to specify the position of a widget, and you // don't want to specify the position in slate units, instead, you // want to specify the position using fractions: ie, (0,0) is the // upper left corner of the screen, and (1,1) is the lower-right corner. // // One way to accomplish this is to put your widget in the middle cell // of a 3x3 GridPanel. Then, you can position it by adjusting the grid // fill rules. This utility routine can do the math necessary to // correctly populate those fill rules. // // This routine must be passed a 3x3 GridPanel. This will reposition // the middle cell. You must specify the upper-left and lower-right // corners of the middle cell as fractions between (0,0) and (1,1). // // Be aware that if the content of a grid cell overflows the amount of // space allocated for it, then the grid will adjust to make room. // But that will mean that the grid is no longer faithful to the // positions specified in its fill rules. One way to ensure that the // grid remains faithful to its fill rules is to put an Overlay // into the GridPanel cell, then put -1000 padding into the // Overlay's GridPanel slot, then put +1000 padding into the Overlay // slot. The two paddings cancel each other out, leaving the item in // the Overlay at the originally-intended position. But if the item // in the overlay overflows, it doesn't cause the Grid to deform. // Instead, the item exceeds the bounds of the grid cell, but it leaves // the grid cell where it belongs. // UFUNCTION(BlueprintCallable, Category="Widget") static void SetPositionOfGridPanelMiddleCell(UGridPanel *GridPanel, FVector2D UpperLeftXY, FVector2D LowerRightXY); // Get Position of GridPanel Middle Cell // // The routine must be passed a 3x3 GridPanel. This will return the // position of the middle cell of the gridpanel, expressed on a scale // from (0,0) to (1,1). // // The numbers returned by this routine are based entirely on the // GridPanel fill rules. If an item in the grid is overflowing its // allocated space, causing the grid to deform, then that won't be // reflected in the output of this routine. // UFUNCTION(BlueprintPure, Category="Widget") static void GetPositionOfGridPanelMiddleCell(UGridPanel *GridPanel, FVector2D &UpperLeftXY, FVector2D &LowerRightXY); // Check if a given key is used by the specified mapping context. // // This is true if the key is mapped to anything at all within // the specified mapping context. // UFUNCTION(BlueprintCallable, Category = "Input", meta = (ExpandEnumAsExecs="ReturnValue")) static ElxUsedOrNotUsed IsKeyUsedByMappingContext(const FKey &Key, const UInputMappingContext *MappingContext); // Get a key by name. // // Returns the null key if there is no such key. // UFUNCTION(BlueprintPure, Category = "Input|Key") static FKey GetKeyByName(const FName &Name); // Get a key by name string. // // Returns the null key if there is no such key. // UFUNCTION(BlueprintPure, Category = "Input|Key") static FKey GetKeyByNameString(const FString &Name); // Get the actor's forward vector multiplied by a speed. // If SnapToXY is true, the forward vector is projected // onto the XY plane and renormalized before scaling. // UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Luprex|Utility", meta = (DefaultToSelf = "Actor")) static FVector GetActorForwardVelocity(const AActor *Actor, double Speed = 1.0, bool bSnapToXY = false); };