178 lines
6.2 KiB
C++
178 lines
6.2 KiB
C++
// Fill out your copyright notice in the Description page of Project Settings.
|
|
|
|
|
|
#include "UtilityLibrary.h"
|
|
#include "GameFramework/PlayerController.h"
|
|
#include "EnhancedInputSubsystems.h"
|
|
#include "Kismet/KismetSystemLibrary.h"
|
|
#include "Kismet/GameplayStatics.h"
|
|
|
|
|
|
#define LOCTEXT_NAMESPACE "Luprex Utility"
|
|
|
|
|
|
void UlxUtilityLibrary::CallFunctionByName(UObject *object, const FString &namepart1, const FString &namepart2, const FString &fallback, bool bFailIfNotFound) {
|
|
FString fullname = namepart1 + namepart2;
|
|
if (!IsValid(object)) {
|
|
UE_LOG(LogBlueprint, Error, TEXT("In CallFunctionByName, object passed in is not valid."));
|
|
return;
|
|
}
|
|
UFunction* function = object->FindFunction(FName(*fullname));
|
|
if (function == nullptr) {
|
|
function = object->FindFunction(FName(*fallback));
|
|
if (function == nullptr) {
|
|
if (!bFailIfNotFound) {
|
|
return;
|
|
}
|
|
UE_LOG(LogBlueprint, Error, TEXT("In CallFunctionByName, cannot find the named function or the fallback function"));
|
|
return;
|
|
}
|
|
}
|
|
if (function->ParmsSize != 0) {
|
|
UE_LOG(LogBlueprint, Error, TEXT("CallFunctionByName can only call functions that have no parameters and no return values"));
|
|
return;
|
|
}
|
|
object->ProcessEvent(function, nullptr);
|
|
}
|
|
|
|
FBox UlxUtilityLibrary::GetActorBounds(const AActor *target, bool bOnlyCollidingComponents, bool bIncludeFromChildActors)
|
|
{
|
|
FVector ActorOrigin;
|
|
FVector BoxExtent;
|
|
|
|
// First argument is bOnlyCollidingComponents - if you want to get the bounds for components that don't have collision enabled then set to false
|
|
// Last argument is bIncludeFromChildActors. Usually this won't do anything but if we've child-ed an actor - like a gun child-ed to a character
|
|
// then we wouldn't want the gun to be part of the bounds so set to false
|
|
target->GetActorBounds(bOnlyCollidingComponents, ActorOrigin, BoxExtent, bIncludeFromChildActors);
|
|
|
|
return FBox::BuildAABB(ActorOrigin, BoxExtent);
|
|
}
|
|
|
|
void UlxUtilityLibrary::AddMovementInputRightward(APawn *target, double ScaleValue, bool Force) {
|
|
FRotator rotator = target->GetControlRotation();
|
|
rotator.Pitch = 0.0;
|
|
rotator.Roll = 0.0;
|
|
rotator.Yaw += 90.0;
|
|
FVector vector = rotator.Vector();
|
|
target->AddMovementInput(vector, ScaleValue, Force);
|
|
}
|
|
|
|
void UlxUtilityLibrary::AddMovementInputForward(APawn *target, double ScaleValue, bool Force) {
|
|
FRotator rotator = target->GetControlRotation();
|
|
rotator.Roll = 0.0;
|
|
rotator.Pitch = 0.0;
|
|
FVector vector = rotator.Vector();
|
|
target->AddMovementInput(vector, ScaleValue, Force);
|
|
}
|
|
|
|
UEnhancedInputLocalPlayerSubsystem *UlxUtilityLibrary::GetEnhancedInputLocalPlayerSubsystem(AController *Controller) {
|
|
APlayerController *pc = Cast<APlayerController>(Controller);
|
|
if (pc != nullptr) {
|
|
UEnhancedInputLocalPlayerSubsystem* subsys =
|
|
ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(pc->GetLocalPlayer());
|
|
if (subsys != nullptr) {
|
|
return subsys;
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
// bool UlxUtilityLibrary::LineTraceMultipleLines(const AActor* ReferenceActor, const FVector &Offset,
|
|
// const TArray<FlxTraceStartTraceEnd> &TraceStartAndTraceEnd, ETraceTypeQuery TraceChannel,
|
|
// bool bTraceComplex, const TArray<AActor*>& ActorsToIgnore, EDrawDebugTrace::Type DrawDebugType, FHitResult& OutHit, bool bIgnoreReferenceActor,
|
|
// FLinearColor TraceColor, FLinearColor TraceHitColor, float DrawTime)
|
|
// {
|
|
// OutHit.Init();
|
|
// OutHit.Distance = FLT_MAX;
|
|
// FTransform ReferenceTransform = ReferenceActor->GetActorTransform();
|
|
|
|
// for (const FlxTraceStartTraceEnd &Points : TraceStartAndTraceEnd) {
|
|
// FHitResult OneResult;
|
|
// FVector TraceStart = ReferenceTransform.TransformPosition(Points.TraceStart + Offset);
|
|
// FVector TraceEnd = ReferenceTransform.TransformPosition(Points.TraceEnd + Offset);
|
|
// bool Found = UKismetSystemLibrary::LineTraceSingle(ReferenceActor, TraceStart, TraceEnd, TraceChannel, bTraceComplex,
|
|
// ActorsToIgnore, DrawDebugType, OneResult, bIgnoreReferenceActor, TraceColor, TraceHitColor, DrawTime);
|
|
// if (Found && (OneResult.Distance < OutHit.Distance))
|
|
// {
|
|
// OutHit = OneResult;
|
|
// }
|
|
// }
|
|
// if (OutHit.Distance == FLT_MAX) {
|
|
// OutHit.Distance = 0.0;
|
|
// return false;
|
|
// } else {
|
|
// return true;
|
|
// }
|
|
// }
|
|
|
|
bool UlxUtilityLibrary::LineTraceThroughMousePointer(const APlayerController* PlayerController,
|
|
EMouseSpecificationType MouseSpecification, FVector2D ManualMouseXY, double MaxDistanceFromCamera,
|
|
ETraceTypeQuery TraceChannel, bool bTraceComplex, EDrawDebugTrace::Type DrawDebugType, bool bIgnorePlayerPawn,
|
|
const TArray<AActor*>& ActorsToIgnore, AActor *& Actor, FHitResult& HitResult)
|
|
{
|
|
const FLinearColor TraceColor = FLinearColor::Red;
|
|
const FLinearColor TraceHitColor = FLinearColor::Green;
|
|
const double DrawTime = 1.0;
|
|
|
|
// Zero out the return values.
|
|
Actor = nullptr;
|
|
HitResult.Init();
|
|
|
|
// Sanity check the distance.
|
|
if (MaxDistanceFromCamera <= 0.0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// Make sure there's a player pawn.
|
|
AActor *PlayerPawn = PlayerController->GetPawn();
|
|
if (!PlayerPawn) return false;
|
|
|
|
// Get the Mouse XY.
|
|
FVector2D MouseXY;
|
|
switch (MouseSpecification)
|
|
{
|
|
case EMouseSpecificationType::GetMouseAutomatically:
|
|
{
|
|
double X, Y;
|
|
if (!PlayerController->GetMousePosition(X, Y)) return false;
|
|
MouseXY = FVector2D(X, Y);
|
|
break;
|
|
}
|
|
case EMouseSpecificationType::SpecifyMouseInPixels:
|
|
{
|
|
MouseXY = ManualMouseXY;
|
|
break;
|
|
}
|
|
case EMouseSpecificationType::SpecifyMouseAsZeroToOne:
|
|
{
|
|
int32 VX, VY;
|
|
PlayerController->GetViewportSize(VX, VY);
|
|
if ((VX == 0) || (VY == 0)) return false;
|
|
MouseXY = ManualMouseXY * FVector2D(VX, VY);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Calculate the trace start and trace end positions in world space.
|
|
FVector WorldStart, WorldDirection, WorldEnd;
|
|
if (!UGameplayStatics::DeprojectScreenToWorld(PlayerController, MouseXY, WorldStart, WorldDirection))
|
|
{
|
|
return false;
|
|
}
|
|
WorldEnd = WorldStart + (WorldDirection * MaxDistanceFromCamera);
|
|
|
|
// Find the hit.
|
|
if (UKismetSystemLibrary::LineTraceSingle(PlayerPawn, WorldStart, WorldEnd, TraceChannel, bTraceComplex,
|
|
ActorsToIgnore, DrawDebugType, HitResult, bIgnorePlayerPawn, TraceColor, TraceHitColor, DrawTime))
|
|
{
|
|
Actor = HitResult.GetActor();
|
|
return true;
|
|
}
|
|
|
|
// Fail.
|
|
Actor = nullptr;
|
|
HitResult.Init();
|
|
return false;
|
|
}
|