Compare commits

..

1 Commits

Author SHA1 Message Date
564d0837c5 auto run 2025-12-25 01:20:33 +01:00
22 changed files with 366 additions and 10 deletions

6
.gitmodules vendored
View File

@@ -7,3 +7,9 @@
[submodule "Plugins/FactionSystem"] [submodule "Plugins/FactionSystem"]
path = Plugins/FactionSystem path = Plugins/FactionSystem
url = https://github.com/amasson42/FactionSystem-unreal-plugin.git url = https://github.com/amasson42/FactionSystem-unreal-plugin.git
[submodule "Plugins/InteractionSystem"]
path = Plugins/InteractionSystem
url = https://github.com/amasson42/InteractionSystem-unreal-plugin.git
[submodule "Plugins/SlotBasedInventorySystem"]
path = Plugins/SlotBasedInventorySystem
url = https://github.com/amasson42/SlotBasedInventorySystem-unreal-plugin.git

View File

@@ -65,6 +65,8 @@ FontDPI=72
[/Script/Engine.Engine] [/Script/Engine.Engine]
+ActiveGameNameRedirects=(OldGameName="TP_Blank",NewGameName="/Script/Wailing") +ActiveGameNameRedirects=(OldGameName="TP_Blank",NewGameName="/Script/Wailing")
+ActiveGameNameRedirects=(OldGameName="/Script/TP_Blank",NewGameName="/Script/Wailing") +ActiveGameNameRedirects=(OldGameName="/Script/TP_Blank",NewGameName="/Script/Wailing")
AssetManagerClassName=/Script/GasRpg.GasRpgAssetManager
bUseFixedFrameRate=True
[/Script/AndroidFileServerEditor.AndroidFileServerRuntimeSettings] [/Script/AndroidFileServerEditor.AndroidFileServerRuntimeSettings]
bEnablePlugin=True bEnablePlugin=True

View File

@@ -12,3 +12,5 @@ ProjectDisplayedTitle=NSLOCTEXT("[/Script/EngineSettings]", "AFE249BB43CD5968FD7
bAddPacks=True bAddPacks=True
InsertPack=(PackSource="StarterContent.upack",PackName="StarterContent") InsertPack=(PackSource="StarterContent.upack",PackName="StarterContent")
[/Script/GameplayAbilities.AbilitySystemGlobals]
AbilitySystemGlobalsClassName="/Script/GasRpg.GasRpgAbilitySystemGlobals"

View File

@@ -77,7 +77,7 @@ DefaultViewportMouseLockMode=LockOnCapture
FOVScale=0.011110 FOVScale=0.011110
DoubleClickTime=0.200000 DoubleClickTime=0.200000
DefaultPlayerInputClass=/Script/EnhancedInput.EnhancedPlayerInput DefaultPlayerInputClass=/Script/EnhancedInput.EnhancedPlayerInput
DefaultInputComponentClass=/Script/EnhancedInput.EnhancedInputComponent DefaultInputComponentClass=/Script/GasRpg.GRInputComponent
DefaultTouchInterface=/Engine/MobileResources/HUD/DefaultVirtualJoysticks.DefaultVirtualJoysticks DefaultTouchInterface=/Engine/MobileResources/HUD/DefaultVirtualJoysticks.DefaultVirtualJoysticks
-ConsoleKeys=Tilde -ConsoleKeys=Tilde
+ConsoleKeys=Tilde +ConsoleKeys=Tilde

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,106 @@
// Amasson
#include "Components/AutoRunComponent.h"
#include "Components/SplineComponent.h"
#include "NavigationSystem.h"
#include "NavigationPath.h"
UAutoRunComponent::UAutoRunComponent()
{
PrimaryComponentTick.bCanEverTick = true;
PathSpline = CreateDefaultSubobject<USplineComponent>("PathSpline");
}
void UAutoRunComponent::SetControlledPawn(APawn* Pawn)
{
ControlledPawn = Pawn;
}
void UAutoRunComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
if (bAutoRunning)
if (IsValid(ControlledPawn) && IsValid(PathSpline))
{
const FVector PawnLocation = ControlledPawn->GetActorLocation();
const float ClosePointKey = PathSpline->FindInputKeyClosestToWorldLocation(PawnLocation);
const FVector LocationOnSpline = PathSpline->GetLocationAtSplineInputKey(ClosePointKey, ESplineCoordinateSpace::World);
const FVector SplineDirection = PathSpline->GetDirectionAtSplineInputKey(ClosePointKey, ESplineCoordinateSpace::World);
const FVector NextTargetPoint = PathSpline->GetLocationAtSplineInputKey(FMath::CeilToFloat(ClosePointKey + 0.5), ESplineCoordinateSpace::World);
FVector DirectionToNextTargetPoint = NextTargetPoint - PawnLocation;
DirectionToNextTargetPoint.Normalize();
ControlledPawn->AddMovementInput((SplineDirection + DirectionToNextTargetPoint) / 2);
if (ClosePointKey >= static_cast<float>(PathSpline->GetNumberOfSplinePoints()) - 1.1)
bAutoRunning = false;
}
}
void UAutoRunComponent::StopAutoRun()
{
bAutoRunning = false;
}
void UAutoRunComponent::AutoRunKeyPressed()
{
FollowTime = 0;
bAutoRunning = false;
}
void UAutoRunComponent::AutoRunKeyReleased()
{
if (!IsValid(ControlledPawn))
return;
if (FollowTime < ShortPressThreshold)
{
if (UNavigationPath* NavPath = UNavigationSystemV1::FindPathToLocationSynchronously(this, ControlledPawn->GetActorLocation(), CachedDestination))
{
if (IsValid(PathSpline))
{
PathSpline->ClearSplinePoints();
for (const FVector& PointLoc : NavPath->PathPoints)
{
PathSpline->AddSplinePoint(PointLoc, ESplineCoordinateSpace::World);
}
}
if (!NavPath->PathPoints.IsEmpty())
CachedDestination = NavPath->PathPoints[NavPath->PathPoints.Num() - 1];
OnAutoWalkBegin.Broadcast(this, CachedDestination);
bAutoRunning = true;
}
}
}
void UAutoRunComponent::AutoRunKeyHold(float DeltaTime, const FHitResult& CursorHit)
{
FollowTime += DeltaTime;
if (CursorHit.bBlockingHit)
{
CachedDestination = CursorHit.ImpactPoint;
if (IsValid(ControlledPawn))
{
const FVector WorldDirection = (CachedDestination - ControlledPawn->GetActorLocation()).GetSafeNormal();
ControlledPawn->AddMovementInput(WorldDirection);
}
}
}
bool UAutoRunComponent::IsAtDestination() const
{
if (!IsValid(ControlledPawn))
return false;
const float SquaredDistanceToDestination = (ControlledPawn->GetActorLocation() - CachedDestination).SquaredLength();
const float SquaredAcceptanceRadius = AutoRunAcceptanceRadius * AutoRunAcceptanceRadius;
return SquaredDistanceToDestination <= SquaredAcceptanceRadius;
}

View File

@@ -2,4 +2,102 @@
#include "Player/WLPlayerController.h" #include "Player/WLPlayerController.h"
#include "Components/InteractionControllerComponent.h"
#include "Components/AutoRunComponent.h"
#include "EnhancedInputSubsystems.h"
#include "EnhancedInputComponent.h"
AWLPlayerController::AWLPlayerController()
{
InteractionComponent = CreateDefaultSubobject<UInteractionControllerComponent>("InteractionComponent");
AutoRunComponent = CreateDefaultSubobject<UAutoRunComponent>("AutoRunComponent");
bShowMouseCursor = true;
DefaultMouseCursor = EMouseCursor::Default;
}
void AWLPlayerController::BeginPlay()
{
Super::BeginPlay();
if (UEnhancedInputLocalPlayerSubsystem* InputSubsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(GetLocalPlayer()))
{
checkf(InputContext, TEXT("WLPlayerController: Invalid Input Context"));
InputSubsystem->AddMappingContext(InputContext, 0);
}
FInputModeGameAndUI InputModeData;
InputModeData.SetLockMouseToViewportBehavior(EMouseLockMode::DoNotLock);
InputModeData.SetHideCursorDuringCapture(false);
SetInputMode(InputModeData);
}
void AWLPlayerController::AcknowledgePossession(APawn* P)
{
Super::AcknowledgePossession(P);
AutoRunComponent->SetControlledPawn(P);
}
void AWLPlayerController::SetupInputComponent()
{
Super::SetupInputComponent();
if (UEnhancedInputComponent* EnhancedInputComponent = Cast<UEnhancedInputComponent>(InputComponent))
{
EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &ThisClass::Move);
EnhancedInputComponent->BindAction(HoldPositionAction, ETriggerEvent::Triggered, this, &ThisClass::HoldPositionPressed);
EnhancedInputComponent->BindAction(HoldPositionAction, ETriggerEvent::Completed, this, &ThisClass::HoldPositionReleased);
EnhancedInputComponent->BindAction(AutoRunAction, ETriggerEvent::Started, this, &ThisClass::AutoRunPressed);
EnhancedInputComponent->BindAction(AutoRunAction, ETriggerEvent::Triggered, this, &ThisClass::AutoRunHeld);
EnhancedInputComponent->BindAction(AutoRunAction, ETriggerEvent::Completed, this, &ThisClass::AutoRunReleased);
}
}
void AWLPlayerController::Move(const FInputActionValue& InputActionValue)
{
const FVector2D InputAxisVector = InputActionValue.Get<FVector2D>();
if (InputAxisVector.IsNearlyZero())
return;
AutoRunComponent->StopAutoRun();
const FRotator Rotation = GetControlRotation();
const FRotator YawRotation(0.0f, Rotation.Yaw, 0.0f);
const FRotationMatrix RotationMatrix(YawRotation);
const FVector ForwardVector = RotationMatrix.GetUnitAxis(EAxis::X);
const FVector RightVector = RotationMatrix.GetUnitAxis(EAxis::Y);
if (APawn* ControlledPawn = GetPawn<APawn>())
{
ControlledPawn->AddMovementInput(ForwardVector, InputAxisVector.Y);
ControlledPawn->AddMovementInput(RightVector, InputAxisVector.X);
}
}
void AWLPlayerController::AutoRunPressed()
{
AutoRunComponent->AutoRunKeyPressed();
}
void AWLPlayerController::AutoRunHeld()
{
AutoRunComponent->AutoRunKeyHold(GetWorld()->GetDeltaSeconds(), InteractionComponent->GetCursorHit());
}
void AWLPlayerController::AutoRunReleased()
{
AutoRunComponent->AutoRunKeyReleased();
}
void AWLPlayerController::HoldPositionPressed()
{
AutoRunComponent->HoldPositionPressed();
}
void AWLPlayerController::HoldPositionReleased()
{
AutoRunComponent->HoldPositionReleased();
}

View File

@@ -0,0 +1,73 @@
// Amasson
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "AutoRunComponent.generated.h"
class USplineComponent;
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnAutoWalkBeginSignature, UAutoRunComponent*, AutoRunComponent, FVector, Destination);
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class WAILING_API UAutoRunComponent : public UActorComponent
{
GENERATED_BODY()
public:
UAutoRunComponent();
UPROPERTY(BlueprintAssignable)
FOnAutoWalkBeginSignature OnAutoWalkBegin;
void SetControlledPawn(APawn* Pawn);
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
void StopAutoRun();
void AutoRunKeyPressed();
void AutoRunKeyReleased();
void AutoRunKeyHold(float DeltaTime, const FHitResult& CursorHit);
void HoldPositionPressed()
{
bIsHoldingPosition = true;
}
void HoldPositionReleased()
{
bIsHoldingPosition = false;
}
bool ShouldAutoRun()
{
return !bIsHoldingPosition;
}
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Components")
USplineComponent* GetPathSpline() const { return PathSpline; }
private:
FVector CachedDestination = FVector::ZeroVector;
float FollowTime = 0.0f;
float ShortPressThreshold = 0.2f;
bool bAutoRunning = false;
UPROPERTY(EditDefaultsOnly)
float AutoRunAcceptanceRadius = 50.0f;
UPROPERTY(VisibleAnywhere)
TObjectPtr<USplineComponent> PathSpline;
TObjectPtr<APawn> ControlledPawn;
bool bIsHoldingPosition;
bool IsAtDestination() const;
};

View File

@@ -6,6 +6,8 @@
#include "Player/GRPlayerController.h" #include "Player/GRPlayerController.h"
#include "WLPlayerController.generated.h" #include "WLPlayerController.generated.h"
class UInputAction;
/** /**
* *
*/ */
@@ -14,4 +16,45 @@ class WAILING_API AWLPlayerController : public AGRPlayerController
{ {
GENERATED_BODY() GENERATED_BODY()
protected:
AWLPlayerController();
virtual void BeginPlay() override;
virtual void AcknowledgePossession(APawn* P) override;
virtual void SetupInputComponent() override;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components", meta = (AllowPrivateAccess = true))
TObjectPtr<class UInteractionControllerComponent> InteractionComponent;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "AutoRun", meta = (AllowPrivateAccess = true))
TObjectPtr<class UAutoRunComponent> AutoRunComponent;
UPROPERTY(EditAnywhere, Category = "Input")
TObjectPtr<class UInputMappingContext> InputContext;
UPROPERTY(EditAnywhere, Category = "Input")
TObjectPtr<UInputAction> MoveAction;
UPROPERTY(EditAnywhere, Category = "Input")
TObjectPtr<UInputAction> HoldPositionAction;
UPROPERTY(EditAnywhere, Category = "Input")
TObjectPtr<UInputAction> AutoRunAction;
private:
void Move(const struct FInputActionValue& InputActionValue);
void AutoRunPressed();
void AutoRunHeld();
void AutoRunReleased();
void HoldPositionPressed();
void HoldPositionReleased();
}; };

View File

@@ -20,6 +20,10 @@
"TargetAllowList": [ "TargetAllowList": [
"Editor" "Editor"
] ]
},
{
"Name": "FunctionalTestingEditor",
"Enabled": true
} }
] ]
} }