Compare commits

..

3 Commits

Author SHA1 Message Date
564d0837c5 auto run 2025-12-25 01:20:33 +01:00
6edcd72294 Player controller class 2024-08-24 15:42:32 +02:00
848eb649ab Base Character 2024-08-19 11:57:18 +02:00
41 changed files with 461 additions and 20 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.

Binary file not shown.

Binary file not shown.

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

@@ -0,0 +1,5 @@
// Copyright by amasson
#include "Data/WLCharacterKit.h"

View File

@@ -0,0 +1,103 @@
// Copyright by amasson
#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

@@ -0,0 +1,18 @@
// Copyright by amasson
#pragma once
#include "CoreMinimal.h"
#include "Data/GRCharacterKit.h"
#include "WLCharacterKit.generated.h"
/**
*
*/
UCLASS()
class WAILING_API UWLCharacterKit : public UGRCharacterKit
{
GENERATED_BODY()
};

View File

@@ -0,0 +1,60 @@
// Copyright by amasson
#pragma once
#include "CoreMinimal.h"
#include "Player/GRPlayerController.h"
#include "WLPlayerController.generated.h"
class UInputAction;
/**
*
*/
UCLASS()
class WAILING_API AWLPlayerController : public AGRPlayerController
{
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

@@ -10,7 +10,14 @@ public class Wailing : ModuleRules
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" }); PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" });
PrivateDependencyModuleNames.AddRange(new string[] { }); PrivateDependencyModuleNames.AddRange(new string[] {
"AIModule",
"EnhancedInput",
"FactionSystem",
"GasRpg",
"NavigationSystem",
"InteractionSystem",
});
// Uncomment if you are using Slate UI // Uncomment if you are using Slate UI
// PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" }); // PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });

View File

@@ -7,7 +7,10 @@
{ {
"Name": "Wailing", "Name": "Wailing",
"Type": "Runtime", "Type": "Runtime",
"LoadingPhase": "Default" "LoadingPhase": "Default",
"AdditionalDependencies": [
"GasRpg"
]
} }
], ],
"Plugins": [ "Plugins": [
@@ -17,6 +20,10 @@
"TargetAllowList": [ "TargetAllowList": [
"Editor" "Editor"
] ]
},
{
"Name": "FunctionalTestingEditor",
"Enabled": true
} }
] ]
} }