diff --git a/Content/Developers/Wdev/Robots/BP_Stretch.uasset b/Content/Developers/Wdev/Robots/BP_Stretch.uasset index 9c18e16e..d9701222 100644 Binary files a/Content/Developers/Wdev/Robots/BP_Stretch.uasset and b/Content/Developers/Wdev/Robots/BP_Stretch.uasset differ diff --git a/Source/LuckyWorldV2/Private/Gameplay/Robot/Components/Movement/LRMC_Stretch.cpp b/Source/LuckyWorldV2/Private/Gameplay/Robot/Components/Movement/LRMC_Stretch.cpp index 9f257305..7d050906 100644 --- a/Source/LuckyWorldV2/Private/Gameplay/Robot/Components/Movement/LRMC_Stretch.cpp +++ b/Source/LuckyWorldV2/Private/Gameplay/Robot/Components/Movement/LRMC_Stretch.cpp @@ -4,6 +4,7 @@ #include "Gameplay/Robot/Components/Movement/LRMC_Stretch.h" #include "Actors/MujocoVolumeActor.h" #include "Gameplay/Robot/LuckyRobotPawnBase.h" +#include "Kismet/KismetMathLibrary.h" void ULRMC_Stretch::PerformMovement(float DeltaTime, const ERobotInputHandlingMethod InputHandlingMethod, const ERobotInputType InputType, const FVector2D& InputValues) @@ -19,58 +20,119 @@ void ULRMC_Stretch::PerformMovement(float DeltaTime, const ERobotInputHandlingMe switch (PreviousInputType) { case ERobotInputType::None: + StopMovement(); break; case ERobotInputType::Move: if (FMath::IsNearlyZero(InputValues.X)) { PreviousInputType = ERobotInputType::None; + StopMovement(); } else { - Move(InputValues.X); + PreviousInputType = ERobotInputType::Move; + Move(DeltaTime, InputValues); } break; case ERobotInputType::Turn: if (FMath::IsNearlyZero(InputValues.Y)) { PreviousInputType = ERobotInputType::None; + StopMovement(); } else { - Turn(InputValues.Y); + PreviousInputType = ERobotInputType::Turn; + Turn(DeltaTime, InputValues.Y); } break; case ERobotInputType::Pathfinding: + if (FMath::IsNearlyZero(InputValues.X)) + { + PreviousInputType = ERobotInputType::None; + } + else + { + PreviousInputType = ERobotInputType::Move; + Move(DeltaTime, InputValues); + } break; } break; case ERobotInputType::Move: { PreviousInputType = ERobotInputType::Move; - Move(InputValues.X); + Move(DeltaTime, InputValues); } break; case ERobotInputType::Turn: { PreviousInputType = ERobotInputType::Turn; - Turn(InputValues.Y); + Turn(DeltaTime, InputValues.Y); } break; case ERobotInputType::Pathfinding: - break; + switch (PathfindingInputType) { + case ERobotInputType::None: + break; + case ERobotInputType::Move: + PreviousInputType = ERobotInputType::Move; + Move(DeltaTime, InputValues); + break; + case ERobotInputType::Turn: + PreviousInputType = ERobotInputType::Turn; + Turn(DeltaTime, InputValues.Y); + break; + case ERobotInputType::Pathfinding: + break; + } } } -void ULRMC_Stretch::Move(const float InValue) const +void ULRMC_Stretch::Move(const float DeltaTime, const FVector2D& InputValues) const { - if (GetMujocoVolumeActor()) + if (GetOwningRobot() && GetMujocoVolumeActor()) { - GetMujocoVolumeActor()->SetActuatorValueByIndex(0, InValue); - GetMujocoVolumeActor()->SetActuatorValueByIndex(1, InValue); + float Input_0 = InputValues.X; + float Input_1 = InputValues.X; + + const float TargetSpeed = GetTargetSpeed(); + + const FVector Forward = GetRobotForwardVector(); + const FVector DirectionToTarget = (PathfindingTargetLocation - GetRobotLocation()).GetSafeNormal(); + const float DirectionDot = FVector::DotProduct(Forward, DirectionToTarget); + + const bool bRight = FVector::DotProduct(DirectionToTarget, GetRobotRightVector()) >= 0.f; + const float DirectionDelta = FMath::Abs(1.f - DirectionDot); + const float DirectionOffset = FMath::Min(DirectionDelta * TargetSpeed * 10.f, TargetSpeed) * 2.f; + UE_LOG(LogTemp, Warning, TEXT("RobotMove :: DirectionOffset (%f)"), DirectionOffset); + + + if (!FMath::IsNearlyZero(DirectionOffset, 0.01f)) + { + if (bRight) + { + Input_1 -= DirectionOffset; + } + else + { + Input_0 -= DirectionOffset; + } + } + + const float TargetSpeedMod = GetTargetSpeedMod() * 0.5f; + + Input_0 = FMath::Min(Input_0, GetTargetSpeed()) * TargetSpeedMod; + Input_1 = FMath::Min(Input_1, GetTargetSpeed()) * TargetSpeedMod; + + UE_LOG(LogTemp, Warning, TEXT("RobotMove Inputs :: Left [%f] :: Right [%f]"), Input_0, Input_1); + + GetMujocoVolumeActor()->SetActuatorValueByIndex(0, Input_0); + GetMujocoVolumeActor()->SetActuatorValueByIndex(1, Input_1); } } -void ULRMC_Stretch::Turn(const float InValue) const +void ULRMC_Stretch::Turn(const float DeltaTime, const float InValue) const { if (GetMujocoVolumeActor()) { @@ -78,4 +140,13 @@ void ULRMC_Stretch::Turn(const float InValue) const GetMujocoVolumeActor()->SetActuatorValueByIndex(0, InValue * -TurnMod); GetMujocoVolumeActor()->SetActuatorValueByIndex(1, InValue * TurnMod); } -} \ No newline at end of file +} + +void ULRMC_Stretch::StopMovement() +{ + if (GetMujocoVolumeActor()) + { + GetMujocoVolumeActor()->SetActuatorValueByIndex(0, 0.f); + GetMujocoVolumeActor()->SetActuatorValueByIndex(1, 0.f); + } +} diff --git a/Source/LuckyWorldV2/Private/Gameplay/Robot/Components/Movement/LuckyRobotMovementComponent.cpp b/Source/LuckyWorldV2/Private/Gameplay/Robot/Components/Movement/LuckyRobotMovementComponent.cpp index 167997f6..b0cef232 100644 --- a/Source/LuckyWorldV2/Private/Gameplay/Robot/Components/Movement/LuckyRobotMovementComponent.cpp +++ b/Source/LuckyWorldV2/Private/Gameplay/Robot/Components/Movement/LuckyRobotMovementComponent.cpp @@ -3,6 +3,7 @@ #include "Gameplay/Robot/Components/Movement/LuckyRobotMovementComponent.h" #include "Actors/MujocoVolumeActor.h" +#include "Components/SplineComponent.h" #include "Gameplay/Robot/LuckyRobotPawnBase.h" #include "Kismet/KismetMathLibrary.h" @@ -19,13 +20,25 @@ void ULuckyRobotMovementComponent::TickComponent(float DeltaTime, enum ELevelTic if (GetOwningRobot()) { + const FVector CurrentLocation = GetRobotLocation(); + CurrentRobotSpeed = UKismetMathLibrary::SafeDivide(FVector::Distance(CurrentLocation, PreviousLocation), DeltaTime); + + if (IsPathfinding()) + { + HandlePathfindingInputs(DeltaTime); + } + InterpolateSpeedValues(DeltaTime, GetOwningRobot()->GetAccelerationRate(), GetOwningRobot()->GetDecelerationRate()); PerformMovement(DeltaTime, RobotSettings.InputHandlingMethod, GetOwningRobot()->GetCurrentInputType(), CurrentSpeedValues); + + PreviousLocation = CurrentLocation; + + UE_LOG(LogTemp, Warning, TEXT("CurrentRobotSpeed (%f)"), CurrentRobotSpeed); } } void ULuckyRobotMovementComponent::BeginPlay() -{ +{ Super::BeginPlay(); } @@ -39,6 +52,7 @@ void ULuckyRobotMovementComponent::InitializeMovementComponent(ALuckyRobotPawnBa { RobotSettings = GetOwningRobot()->RobotSettings; MujocoVolumeActor = GetOwningRobot()->GetMujocoVolumeActor(); + PreviousLocation = GetRobotLocation(); } SetComponentTickEnabled(true); @@ -85,10 +99,30 @@ FVector ULuckyRobotMovementComponent::GetRobotRightVector() const return FVector::ZeroVector; } +FRobotSplinePath ULuckyRobotMovementComponent::GetNavPath() const +{ + if (GetOwningRobot()) + { + return GetOwningRobot()->GetCurrentNavPath(); + } + + return FRobotSplinePath(); +} + +bool ULuckyRobotMovementComponent::IsPathfinding() const +{ + if (GetOwningRobot()) + { + return GetOwningRobot()->IsPathfinding(); + } + + return false; +} + void ULuckyRobotMovementComponent::PerformMovement(float DeltaTime, const ERobotInputHandlingMethod InputHandlingMethod, const ERobotInputType InputType, const FVector2D& SpeedValues) { //UE_LOG(LogTemp, Warning, TEXT("ULuckyRobotMovementComponent::PerformMovement IS NOT IMPLEMENTED")); - UE_LOG(LogTemp, Warning, TEXT("ULuckyRobotMovementComponent::PerformMovement [ DeltaTime (%f) :: InputHandlingMethod (%s) :: InputType (%s) :: InputValues (%s) ]"), DeltaTime, *UEnum::GetValueAsString(InputHandlingMethod), *UEnum::GetValueAsString(InputType), *SpeedValues.ToString()); + //UE_LOG(LogTemp, Warning, TEXT("ULuckyRobotMovementComponent::PerformMovement [ DeltaTime (%f) :: InputHandlingMethod (%s) :: InputType (%s) :: InputValues (%s) ]"), DeltaTime, *UEnum::GetValueAsString(InputHandlingMethod), *UEnum::GetValueAsString(InputType), *SpeedValues.ToString()); } void ULuckyRobotMovementComponent::InterpolateSpeedValues(const float DeltaTime, const float Acceleration, const float Deceleration) @@ -98,7 +132,9 @@ void ULuckyRobotMovementComponent::InterpolateSpeedValues(const float DeltaTime, FVector2D TargetSpeedValues = GetOwningRobot()->GetMovementInputValues() * GetOwningRobot()->GetTargetSpeed(); const FVector Current = FVector(CurrentSpeedValues.X, CurrentSpeedValues.Y, 0.f); - FVector Target = FVector(TargetSpeedValues.X, TargetSpeedValues.Y, 0.f); + const FVector RawTarget = FVector(TargetSpeedValues.X, TargetSpeedValues.Y, 0.f); + FVector Target = IsPathfinding() ? RawTarget.GetClampedToMaxSize(PathfindingTargetSpeed) : RawTarget; + UE_LOG(LogTemp, Warning, TEXT("PathfindingTargetSpeed (%f)"), PathfindingTargetSpeed); if (RobotSettings.InputHandlingMethod == ERobotInputHandlingMethod::SingleInput) { @@ -124,6 +160,161 @@ void ULuckyRobotMovementComponent::InterpolateSpeedValues(const float DeltaTime, CurrentSpeedValues = FVector2D(MoveRate, TurnRate); - UE_LOG(LogTemp, Warning, TEXT("ULuckyRobotMovementComponent::InterpolateSpeedValues (%s)"), *CurrentSpeedValues.ToString()); + UE_LOG(LogTemp, Warning, TEXT("ULuckyRobotMovementComponent::InterpolatedSpeedValues (%s)"), *CurrentSpeedValues.ToString()); } -} \ No newline at end of file +} + +void ULuckyRobotMovementComponent::HandlePathfindingInputs(const float DeltaTime) +{ + if (GetOwningRobot()) + { + if (USplineComponent* SplineComp = GetNavPath().GetSplinePath()) + { + constexpr float SplineDistanceTolerance = 15.f; + constexpr float SplineDirectionTolerance = 0.95f; + + const bool bSingleInput = GetOwningRobot()->RobotSettings.InputHandlingMethod == ERobotInputHandlingMethod::SingleInput; + const FTransform CurrentTransform = GetOwningRobot()->GetTransform(); + const float SplineDistance = SplineComp->GetDistanceAlongSplineAtLocation(CurrentTransform.GetLocation(), ESplineCoordinateSpace::World); + const FVector SplineLocation = SplineComp->GetWorldLocationAtDistanceAlongSpline(SplineDistance); + const float DistanceToSpline = FVector::Distance(CurrentTransform.GetLocation(), SplineLocation); + PathfindingTargetLocation = bSingleInput ? GetSplineTargetPointLocation(SplineDistance) : GetSplineTargetLocation(SplineDistance); + PathfindingDestination = GetOwningRobot()->GetPathfindingDestination(); + DrawDebugLine(GetWorld(), PathfindingTargetLocation, PathfindingTargetLocation + FVector(0.f, 0.f, 100.f), bSingleInput ? FColor::Purple : FColor::Yellow, false, 0.02f, 0, 3.f); + DrawDebugLine(GetWorld(), CurrentTransform.GetLocation(), CurrentTransform.GetLocation() + GetRobotForwardVector() * 100.f, FColor::Green, false, 0.02f, 0, 3.f); + DrawDebugLine(GetWorld(), CurrentTransform.GetLocation(), CurrentTransform.GetLocation() + GetRobotForwardVector() * -100.f, FColor::Blue, false, 0.02f, 0, 3.f); + + if (FVector::Distance(CurrentTransform.GetLocation(), PathfindingDestination) <= PathfindingDestinationTolerance) + { + GetOwningRobot()->PathfindingComplete(true); + return; + } + + PathfindingTargetSpeed = GetSplineSpeed(SplineDistance); + + if (DistanceToSpline > SplineDistanceTolerance) + { + if (bSingleInput) + { + const FVector DirectionToSpline = (SplineLocation - CurrentTransform.GetLocation()).GetSafeNormal(); + const float DirectionDot = FVector::DotProduct(GetRobotForwardVector(), DirectionToSpline); + if (DirectionDot >= SplineDirectionTolerance) + { + GetOwningRobot()->SetPathfindingInputValues(FVector2D(1.f, 0.f)); + PathfindingInputType = ERobotInputType::Move; + } + else + { + const bool bTurnRight = FVector::DotProduct(GetRobotRightVector(), DirectionToSpline) >= 0.f; + const float DirectionDiscrepancy = (2.f - DirectionDot + 1.f) * bTurnRight ? -1.f : 1.f; + const float TurnRate = UKismetMathLibrary::FInterpTo(1.f, DirectionDiscrepancy, DeltaTime, 1.f); + GetOwningRobot()->SetPathfindingInputValues(FVector2D(0.f, TurnRate)); + PathfindingInputType = ERobotInputType::Turn; + } + } + } + else + { + const FVector DirectionToPath = (PathfindingTargetLocation - CurrentTransform.GetLocation()).GetSafeNormal(); + const float DirectionDot = FVector::DotProduct(GetRobotForwardVector(), DirectionToPath); + UE_LOG(LogTemp, Warning, TEXT("DirectionDot :: %f"), DirectionDot); + const float TurnRate = FVector::DotProduct(GetRobotRightVector(), DirectionToPath) >= 0.f ? -1.f : 1.f; + if (DirectionDot >= SplineDirectionTolerance) + { + const float AdjustedTurnRate = TurnRate * (1.f - DirectionDot); + GetOwningRobot()->SetPathfindingInputValues(FVector2D(1.f, AdjustedTurnRate)); + PathfindingInputType = ERobotInputType::Move; + } + else + { + if (bSingleInput) + { + GetOwningRobot()->SetPathfindingInputValues(FVector2D(0.f, TurnRate)); + PathfindingInputType = ERobotInputType::Turn; + } + else + { + const float AdjustedTurnRate = TurnRate * (1.f - DirectionDot); + GetOwningRobot()->SetPathfindingInputValues(FVector2D(GetOwningRobot()->GetMovementInputValues().X, AdjustedTurnRate)); + PathfindingInputType = ERobotInputType::Move; + } + } + } + } + } +} + +FVector ULuckyRobotMovementComponent::GetSplineTargetLocation(const float CurrentDistance) const +{ + if (GetNavPath().GetSplinePath()) + { + const float ForwardPathCheck = FMath::Clamp(GetTargetSpeed() * 0.5f, 20.f, 50.f); + const float SplineCheckDistance = CurrentDistance + ForwardPathCheck; + if (SplineCheckDistance >= GetNavPath().GetSplinePath()->GetSplineLength()) + { + return PathfindingDestination; + } + + return GetNavPath().GetSplinePath()->GetWorldLocationAtDistanceAlongSpline(CurrentDistance + ForwardPathCheck); + } + + return GetRobotLocation(); +} + +FVector ULuckyRobotMovementComponent::GetSplineTargetPointLocation(const float CurrentDistance) const +{ + if (GetNavPath().GetSplinePath()) + { + const int32 SplinePoints = GetNavPath().GetSplinePath()->GetNumberOfSplinePoints(); + float NextSplinePointDistance = GetNavPath().GetSplinePath()->GetSplineLength(); + int32 NextSplinePointIndex = 0; + for (int32 x = 0; x < SplinePoints; x++) + { + const float PointDistance = GetNavPath().GetSplinePath()->GetDistanceAlongSplineAtSplinePoint(x); + if (PointDistance > CurrentDistance && PointDistance < NextSplinePointDistance) + { + NextSplinePointDistance = PointDistance; + NextSplinePointIndex = x; + } + } + + return GetNavPath().GetSplinePath()->GetWorldLocationAtSplinePoint(NextSplinePointIndex); + } + + return GetRobotLocation(); +} + +float ULuckyRobotMovementComponent::GetSplineSpeed(const float CurrentDistance) const +{ + if (GetOwningRobot()) + { + return GetOwningRobot()->GetCurrentNavPath().SplinePathSpeedModifier.EditorCurveData.Eval(CurrentDistance); + } + + return 5.f; +} + +float ULuckyRobotMovementComponent::GetSpeedLimit() const +{ + if (GetOwningRobot()) + { + return GetOwningRobot()->RobotSettings.SpeedLimit; + } + + return 5.f; +} + +void ULuckyRobotMovementComponent::StopMovement() +{ + // +} + +float ULuckyRobotMovementComponent::GetTargetSpeed() const +{ + return IsPathfinding() ? PathfindingTargetSpeed : GetSpeedLimit(); +} + +float ULuckyRobotMovementComponent::GetTargetSpeedMod() const +{ + return UKismetMathLibrary::SafeDivide(GetTargetSpeed(), CurrentRobotSpeed); +} diff --git a/Source/LuckyWorldV2/Private/Gameplay/Robot/Data/RobotSettings.cpp b/Source/LuckyWorldV2/Private/Gameplay/Robot/Data/RobotSettings.cpp index ca155dce..6b326472 100644 --- a/Source/LuckyWorldV2/Private/Gameplay/Robot/Data/RobotSettings.cpp +++ b/Source/LuckyWorldV2/Private/Gameplay/Robot/Data/RobotSettings.cpp @@ -171,14 +171,16 @@ void FRobotSplinePath::RegenerateSplinePathValues() const float PathEndMod = DistanceToPathEnd <= SplinePredictionDistance ? FMath::Max(UKismetMathLibrary::SafeDivide(DistanceToPathEnd, SplinePredictionDistance), 0.f) : 1.f; const FVector IntervalTangent = GetSplinePath()->GetTangentAtDistanceAlongSpline(SplineDistance, ESplineCoordinateSpace::Local); const float IntervalCurve = FMath::Min(IntervalTangent.Length(), TangentClamp); - const float IntervalAlpha = UKismetMathLibrary::SafeDivide(IntervalCurve, TangentClamp); + const float IntervalAlpha = FMath::Max(1.f - UKismetMathLibrary::SafeDivide(IntervalCurve, TangentClamp), 0.f); const float SpeedMod = (MaxSpeedMod - IntervalAlpha) * PathEndMod; - const float ClampedSpeed = FMath::Min(SpeedLimit * SpeedMod, SpeedLimit * MinSpeedMod); + const float ClampedSpeed = FMath::Max(SpeedLimit * SpeedMod, SpeedLimit * MinSpeedMod); SplinePathSpeedModifier.EditorCurveData.AddKey(SplineDistance, ClampedSpeed); } } } + PathfindingDestination = GetSplinePath()->GetWorldLocationAtDistanceAlongSpline(SplineLength); + // begin debug const int32 SplineIntervals = UKismetMathLibrary::SafeDivide(SplineLength, SplinePrecision); diff --git a/Source/LuckyWorldV2/Private/Gameplay/Robot/LuckyRobotPawnBase.cpp b/Source/LuckyWorldV2/Private/Gameplay/Robot/LuckyRobotPawnBase.cpp index 2c9f66de..262655ca 100644 --- a/Source/LuckyWorldV2/Private/Gameplay/Robot/LuckyRobotPawnBase.cpp +++ b/Source/LuckyWorldV2/Private/Gameplay/Robot/LuckyRobotPawnBase.cpp @@ -91,6 +91,8 @@ void ALuckyRobotPawnBase::Tick(float DeltaTime) // { // IncrementCurrentTask(); // } + + UE_LOG(LogTemp, Warning, TEXT("ROBOT TARGET SPEED %f"), TargetSpeed); } void ALuckyRobotPawnBase::NotifyControllerChanged() @@ -259,6 +261,20 @@ void ALuckyRobotPawnBase::TogglePathfinding(const FInputActionValue& Value) CurrentInputType = IsPathfinding() ? ERobotInputType::None : ERobotInputType::Pathfinding; } +void ALuckyRobotPawnBase::BeginPathfinding() +{ + PreviousInputType = ERobotInputType::None; + CurrentInputType = ERobotInputType::Pathfinding; +} + +void ALuckyRobotPawnBase::PathfindingComplete(const bool bSuccess) +{ + CurrentInputType = ERobotInputType::None; + PreviousInputType = ERobotInputType::Pathfinding; + + UE_LOG(LogTemp, Warning, TEXT("ALuckyRobotPawnBase::PathfindingComplete")); +} + void ALuckyRobotPawnBase::RemoveMujocoVolumeActor() { if (GetMujocoVolumeActor()) @@ -294,6 +310,10 @@ void ALuckyRobotPawnBase::SetRobotNavPath(const FRobotNavPath& InRobotNavPath) void ALuckyRobotPawnBase::Internal_RobotNavPathChanged(const FRobotSplinePath& NewNavPath) { + // testing + BeginPathfinding(); + // + RobotNavPathChanged(NewNavPath); } diff --git a/Source/LuckyWorldV2/Public/Gameplay/Robot/Components/Movement/LRMC_Stretch.h b/Source/LuckyWorldV2/Public/Gameplay/Robot/Components/Movement/LRMC_Stretch.h index 648cf4cc..7cbbff70 100644 --- a/Source/LuckyWorldV2/Public/Gameplay/Robot/Components/Movement/LRMC_Stretch.h +++ b/Source/LuckyWorldV2/Public/Gameplay/Robot/Components/Movement/LRMC_Stretch.h @@ -18,6 +18,7 @@ public: protected: ERobotInputType PreviousInputType = ERobotInputType::None; - void Move(const float InValue) const; - void Turn(const float InValue) const; + void Move(const float DeltaTime, const FVector2D& InputValues) const; + void Turn(const float DeltaTime, const float InValue) const; + virtual void StopMovement() override; }; diff --git a/Source/LuckyWorldV2/Public/Gameplay/Robot/Components/Movement/LuckyRobotMovementComponent.h b/Source/LuckyWorldV2/Public/Gameplay/Robot/Components/Movement/LuckyRobotMovementComponent.h index 08943bfa..13a04458 100644 --- a/Source/LuckyWorldV2/Public/Gameplay/Robot/Components/Movement/LuckyRobotMovementComponent.h +++ b/Source/LuckyWorldV2/Public/Gameplay/Robot/Components/Movement/LuckyRobotMovementComponent.h @@ -40,6 +40,21 @@ public: UFUNCTION(BlueprintPure, Category = "Robot Values") FVector GetRobotRightVector() const; + UFUNCTION(BlueprintPure, Category = "Robot Values") + FRobotSplinePath GetNavPath() const; + + bool IsPathfinding() const; + void HandlePathfindingInputs(const float DeltaTime); + + FVector GetSplineTargetLocation(const float CurrentDistance) const; + FVector GetSplineTargetPointLocation(const float CurrentDistance) const; + float GetSplineSpeed(const float CurrentDistance) const; + float GetSpeedLimit() const; + + virtual void StopMovement(); + float GetTargetSpeed() const; + float GetTargetSpeedMod() const; + protected: virtual void BeginPlay() override; @@ -48,8 +63,16 @@ protected: FRobotSettings RobotSettings = FRobotSettings(); - //virtual void EvaluateRobotPath(); + ERobotInputType PathfindingInputType = ERobotInputType::None; + virtual void InterpolateSpeedValues(const float DeltaTime, const float Acceleration, const float Deceleration); FVector2D CurrentSpeedValues = FVector2D::ZeroVector; + float PathfindingTargetSpeed = 0.f; + float PathfindingDestinationTolerance = 10.f; + FVector PathfindingTargetLocation = FVector::ZeroVector; + FVector PathfindingDestination = FVector::ZeroVector; + + float CurrentRobotSpeed = 0.f; + FVector PreviousLocation = FVector::ZeroVector; }; \ No newline at end of file diff --git a/Source/LuckyWorldV2/Public/Gameplay/Robot/Data/RobotSettings.h b/Source/LuckyWorldV2/Public/Gameplay/Robot/Data/RobotSettings.h index afe89433..02419421 100644 --- a/Source/LuckyWorldV2/Public/Gameplay/Robot/Data/RobotSettings.h +++ b/Source/LuckyWorldV2/Public/Gameplay/Robot/Data/RobotSettings.h @@ -84,6 +84,9 @@ struct FRobotSplinePath UPROPERTY(BlueprintReadOnly, Category = "Robot Spline Path") FRuntimeFloatCurve SplinePathSpeedModifier = FRuntimeFloatCurve(); + UPROPERTY(BlueprintReadOnly, Category = "Robot Spline Path") + FVector PathfindingDestination = FVector::ZeroVector; + ALuckyRobotPawnBase* GetRobot() const { return Robot.Get(); } void GenerateSplinePath(ALuckyRobotPawnBase* InRobot, const FRobotNavPath& InNavPath); void RegenerateSplinePathValues(); diff --git a/Source/LuckyWorldV2/Public/Gameplay/Robot/LuckyRobotPawnBase.h b/Source/LuckyWorldV2/Public/Gameplay/Robot/LuckyRobotPawnBase.h index 7985459d..8e754896 100644 --- a/Source/LuckyWorldV2/Public/Gameplay/Robot/LuckyRobotPawnBase.h +++ b/Source/LuckyWorldV2/Public/Gameplay/Robot/LuckyRobotPawnBase.h @@ -158,6 +158,7 @@ public: void Look(const FInputActionValue& Value); void TogglePathfinding(const FInputActionValue& Value); + void BeginPathfinding(); UFUNCTION(BlueprintPure, Category = "Lucky Robot Pawn") ERobotInputType GetCurrentInputType() const { return CurrentInputType; } @@ -186,12 +187,19 @@ public: UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input") float TurnModifier = 1.f; + UFUNCTION(BlueprintCallable, Category = "Input") + void SetPathfindingInputValues(const FVector2D InValues = FVector2D::ZeroVector) { CachedMovementInputValues = InValues; } + + bool IsPathfinding() const { return CurrentInputType == ERobotInputType::Pathfinding; } + FVector GetPathfindingDestination() const { return CurrentSplinePath.PathfindingDestination; } + + void PathfindingComplete(const bool bSuccess = false); + protected: virtual void BeginPlay() override; bool HasMovementValue() const; bool HasTurnValue() const; - bool IsPathfinding() const { return CurrentInputType == ERobotInputType::Pathfinding; } void RemoveMujocoVolumeActor();