Robot Movement WIP
- Robot Movement semi functional for CombinedInput types
This commit is contained in:
parent
a028ed8caf
commit
e79570aeae
Binary file not shown.
@ -4,6 +4,7 @@
|
|||||||
#include "Gameplay/Robot/Components/Movement/LRMC_Stretch.h"
|
#include "Gameplay/Robot/Components/Movement/LRMC_Stretch.h"
|
||||||
#include "Actors/MujocoVolumeActor.h"
|
#include "Actors/MujocoVolumeActor.h"
|
||||||
#include "Gameplay/Robot/LuckyRobotPawnBase.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)
|
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)
|
switch (PreviousInputType)
|
||||||
{
|
{
|
||||||
case ERobotInputType::None:
|
case ERobotInputType::None:
|
||||||
|
StopMovement();
|
||||||
break;
|
break;
|
||||||
case ERobotInputType::Move:
|
case ERobotInputType::Move:
|
||||||
if (FMath::IsNearlyZero(InputValues.X))
|
if (FMath::IsNearlyZero(InputValues.X))
|
||||||
{
|
{
|
||||||
PreviousInputType = ERobotInputType::None;
|
PreviousInputType = ERobotInputType::None;
|
||||||
|
StopMovement();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Move(InputValues.X);
|
PreviousInputType = ERobotInputType::Move;
|
||||||
|
Move(DeltaTime, InputValues);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ERobotInputType::Turn:
|
case ERobotInputType::Turn:
|
||||||
if (FMath::IsNearlyZero(InputValues.Y))
|
if (FMath::IsNearlyZero(InputValues.Y))
|
||||||
{
|
{
|
||||||
PreviousInputType = ERobotInputType::None;
|
PreviousInputType = ERobotInputType::None;
|
||||||
|
StopMovement();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Turn(InputValues.Y);
|
PreviousInputType = ERobotInputType::Turn;
|
||||||
|
Turn(DeltaTime, InputValues.Y);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ERobotInputType::Pathfinding:
|
case ERobotInputType::Pathfinding:
|
||||||
|
if (FMath::IsNearlyZero(InputValues.X))
|
||||||
|
{
|
||||||
|
PreviousInputType = ERobotInputType::None;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PreviousInputType = ERobotInputType::Move;
|
||||||
|
Move(DeltaTime, InputValues);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ERobotInputType::Move:
|
case ERobotInputType::Move:
|
||||||
{
|
{
|
||||||
PreviousInputType = ERobotInputType::Move;
|
PreviousInputType = ERobotInputType::Move;
|
||||||
Move(InputValues.X);
|
Move(DeltaTime, InputValues);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ERobotInputType::Turn:
|
case ERobotInputType::Turn:
|
||||||
{
|
{
|
||||||
PreviousInputType = ERobotInputType::Turn;
|
PreviousInputType = ERobotInputType::Turn;
|
||||||
Turn(InputValues.Y);
|
Turn(DeltaTime, InputValues.Y);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ERobotInputType::Pathfinding:
|
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);
|
float Input_0 = InputValues.X;
|
||||||
GetMujocoVolumeActor()->SetActuatorValueByIndex(1, InValue);
|
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<float>(1.f - DirectionDot);
|
||||||
|
const float DirectionOffset = FMath::Min<float>(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<float>(Input_0, GetTargetSpeed()) * TargetSpeedMod;
|
||||||
|
Input_1 = FMath::Min<float>(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())
|
if (GetMujocoVolumeActor())
|
||||||
{
|
{
|
||||||
@ -78,4 +140,13 @@ void ULRMC_Stretch::Turn(const float InValue) const
|
|||||||
GetMujocoVolumeActor()->SetActuatorValueByIndex(0, InValue * -TurnMod);
|
GetMujocoVolumeActor()->SetActuatorValueByIndex(0, InValue * -TurnMod);
|
||||||
GetMujocoVolumeActor()->SetActuatorValueByIndex(1, InValue * TurnMod);
|
GetMujocoVolumeActor()->SetActuatorValueByIndex(1, InValue * TurnMod);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ULRMC_Stretch::StopMovement()
|
||||||
|
{
|
||||||
|
if (GetMujocoVolumeActor())
|
||||||
|
{
|
||||||
|
GetMujocoVolumeActor()->SetActuatorValueByIndex(0, 0.f);
|
||||||
|
GetMujocoVolumeActor()->SetActuatorValueByIndex(1, 0.f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "Gameplay/Robot/Components/Movement/LuckyRobotMovementComponent.h"
|
#include "Gameplay/Robot/Components/Movement/LuckyRobotMovementComponent.h"
|
||||||
#include "Actors/MujocoVolumeActor.h"
|
#include "Actors/MujocoVolumeActor.h"
|
||||||
|
#include "Components/SplineComponent.h"
|
||||||
#include "Gameplay/Robot/LuckyRobotPawnBase.h"
|
#include "Gameplay/Robot/LuckyRobotPawnBase.h"
|
||||||
#include "Kismet/KismetMathLibrary.h"
|
#include "Kismet/KismetMathLibrary.h"
|
||||||
|
|
||||||
@ -19,13 +20,25 @@ void ULuckyRobotMovementComponent::TickComponent(float DeltaTime, enum ELevelTic
|
|||||||
|
|
||||||
if (GetOwningRobot())
|
if (GetOwningRobot())
|
||||||
{
|
{
|
||||||
|
const FVector CurrentLocation = GetRobotLocation();
|
||||||
|
CurrentRobotSpeed = UKismetMathLibrary::SafeDivide(FVector::Distance(CurrentLocation, PreviousLocation), DeltaTime);
|
||||||
|
|
||||||
|
if (IsPathfinding())
|
||||||
|
{
|
||||||
|
HandlePathfindingInputs(DeltaTime);
|
||||||
|
}
|
||||||
|
|
||||||
InterpolateSpeedValues(DeltaTime, GetOwningRobot()->GetAccelerationRate(), GetOwningRobot()->GetDecelerationRate());
|
InterpolateSpeedValues(DeltaTime, GetOwningRobot()->GetAccelerationRate(), GetOwningRobot()->GetDecelerationRate());
|
||||||
PerformMovement(DeltaTime, RobotSettings.InputHandlingMethod, GetOwningRobot()->GetCurrentInputType(), CurrentSpeedValues);
|
PerformMovement(DeltaTime, RobotSettings.InputHandlingMethod, GetOwningRobot()->GetCurrentInputType(), CurrentSpeedValues);
|
||||||
|
|
||||||
|
PreviousLocation = CurrentLocation;
|
||||||
|
|
||||||
|
UE_LOG(LogTemp, Warning, TEXT("CurrentRobotSpeed (%f)"), CurrentRobotSpeed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ULuckyRobotMovementComponent::BeginPlay()
|
void ULuckyRobotMovementComponent::BeginPlay()
|
||||||
{
|
{
|
||||||
Super::BeginPlay();
|
Super::BeginPlay();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,6 +52,7 @@ void ULuckyRobotMovementComponent::InitializeMovementComponent(ALuckyRobotPawnBa
|
|||||||
{
|
{
|
||||||
RobotSettings = GetOwningRobot()->RobotSettings;
|
RobotSettings = GetOwningRobot()->RobotSettings;
|
||||||
MujocoVolumeActor = GetOwningRobot()->GetMujocoVolumeActor();
|
MujocoVolumeActor = GetOwningRobot()->GetMujocoVolumeActor();
|
||||||
|
PreviousLocation = GetRobotLocation();
|
||||||
}
|
}
|
||||||
|
|
||||||
SetComponentTickEnabled(true);
|
SetComponentTickEnabled(true);
|
||||||
@ -85,10 +99,30 @@ FVector ULuckyRobotMovementComponent::GetRobotRightVector() const
|
|||||||
return FVector::ZeroVector;
|
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)
|
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 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)
|
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();
|
FVector2D TargetSpeedValues = GetOwningRobot()->GetMovementInputValues() * GetOwningRobot()->GetTargetSpeed();
|
||||||
|
|
||||||
const FVector Current = FVector(CurrentSpeedValues.X, CurrentSpeedValues.Y, 0.f);
|
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)
|
if (RobotSettings.InputHandlingMethod == ERobotInputHandlingMethod::SingleInput)
|
||||||
{
|
{
|
||||||
@ -124,6 +160,161 @@ void ULuckyRobotMovementComponent::InterpolateSpeedValues(const float DeltaTime,
|
|||||||
|
|
||||||
CurrentSpeedValues = FVector2D(MoveRate, TurnRate);
|
CurrentSpeedValues = FVector2D(MoveRate, TurnRate);
|
||||||
|
|
||||||
UE_LOG(LogTemp, Warning, TEXT("ULuckyRobotMovementComponent::InterpolateSpeedValues (%s)"), *CurrentSpeedValues.ToString());
|
UE_LOG(LogTemp, Warning, TEXT("ULuckyRobotMovementComponent::InterpolatedSpeedValues (%s)"), *CurrentSpeedValues.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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<float>(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);
|
||||||
|
}
|
||||||
|
@ -171,14 +171,16 @@ void FRobotSplinePath::RegenerateSplinePathValues()
|
|||||||
const float PathEndMod = DistanceToPathEnd <= SplinePredictionDistance ? FMath::Max<float>(UKismetMathLibrary::SafeDivide(DistanceToPathEnd, SplinePredictionDistance), 0.f) : 1.f;
|
const float PathEndMod = DistanceToPathEnd <= SplinePredictionDistance ? FMath::Max<float>(UKismetMathLibrary::SafeDivide(DistanceToPathEnd, SplinePredictionDistance), 0.f) : 1.f;
|
||||||
const FVector IntervalTangent = GetSplinePath()->GetTangentAtDistanceAlongSpline(SplineDistance, ESplineCoordinateSpace::Local);
|
const FVector IntervalTangent = GetSplinePath()->GetTangentAtDistanceAlongSpline(SplineDistance, ESplineCoordinateSpace::Local);
|
||||||
const float IntervalCurve = FMath::Min<float>(IntervalTangent.Length(), TangentClamp);
|
const float IntervalCurve = FMath::Min<float>(IntervalTangent.Length(), TangentClamp);
|
||||||
const float IntervalAlpha = UKismetMathLibrary::SafeDivide(IntervalCurve, TangentClamp);
|
const float IntervalAlpha = FMath::Max<float>(1.f - UKismetMathLibrary::SafeDivide(IntervalCurve, TangentClamp), 0.f);
|
||||||
const float SpeedMod = (MaxSpeedMod - IntervalAlpha) * PathEndMod;
|
const float SpeedMod = (MaxSpeedMod - IntervalAlpha) * PathEndMod;
|
||||||
const float ClampedSpeed = FMath::Min<float>(SpeedLimit * SpeedMod, SpeedLimit * MinSpeedMod);
|
const float ClampedSpeed = FMath::Max<float>(SpeedLimit * SpeedMod, SpeedLimit * MinSpeedMod);
|
||||||
SplinePathSpeedModifier.EditorCurveData.AddKey(SplineDistance, ClampedSpeed);
|
SplinePathSpeedModifier.EditorCurveData.AddKey(SplineDistance, ClampedSpeed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PathfindingDestination = GetSplinePath()->GetWorldLocationAtDistanceAlongSpline(SplineLength);
|
||||||
|
|
||||||
// begin debug
|
// begin debug
|
||||||
|
|
||||||
const int32 SplineIntervals = UKismetMathLibrary::SafeDivide(SplineLength, SplinePrecision);
|
const int32 SplineIntervals = UKismetMathLibrary::SafeDivide(SplineLength, SplinePrecision);
|
||||||
|
@ -91,6 +91,8 @@ void ALuckyRobotPawnBase::Tick(float DeltaTime)
|
|||||||
// {
|
// {
|
||||||
// IncrementCurrentTask();
|
// IncrementCurrentTask();
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
UE_LOG(LogTemp, Warning, TEXT("ROBOT TARGET SPEED %f"), TargetSpeed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ALuckyRobotPawnBase::NotifyControllerChanged()
|
void ALuckyRobotPawnBase::NotifyControllerChanged()
|
||||||
@ -259,6 +261,20 @@ void ALuckyRobotPawnBase::TogglePathfinding(const FInputActionValue& Value)
|
|||||||
CurrentInputType = IsPathfinding() ? ERobotInputType::None : ERobotInputType::Pathfinding;
|
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()
|
void ALuckyRobotPawnBase::RemoveMujocoVolumeActor()
|
||||||
{
|
{
|
||||||
if (GetMujocoVolumeActor())
|
if (GetMujocoVolumeActor())
|
||||||
@ -294,6 +310,10 @@ void ALuckyRobotPawnBase::SetRobotNavPath(const FRobotNavPath& InRobotNavPath)
|
|||||||
|
|
||||||
void ALuckyRobotPawnBase::Internal_RobotNavPathChanged(const FRobotSplinePath& NewNavPath)
|
void ALuckyRobotPawnBase::Internal_RobotNavPathChanged(const FRobotSplinePath& NewNavPath)
|
||||||
{
|
{
|
||||||
|
// testing
|
||||||
|
BeginPathfinding();
|
||||||
|
//
|
||||||
|
|
||||||
RobotNavPathChanged(NewNavPath);
|
RobotNavPathChanged(NewNavPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
ERobotInputType PreviousInputType = ERobotInputType::None;
|
ERobotInputType PreviousInputType = ERobotInputType::None;
|
||||||
|
|
||||||
void Move(const float InValue) const;
|
void Move(const float DeltaTime, const FVector2D& InputValues) const;
|
||||||
void Turn(const float InValue) const;
|
void Turn(const float DeltaTime, const float InValue) const;
|
||||||
|
virtual void StopMovement() override;
|
||||||
};
|
};
|
||||||
|
@ -40,6 +40,21 @@ public:
|
|||||||
UFUNCTION(BlueprintPure, Category = "Robot Values")
|
UFUNCTION(BlueprintPure, Category = "Robot Values")
|
||||||
FVector GetRobotRightVector() const;
|
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:
|
protected:
|
||||||
virtual void BeginPlay() override;
|
virtual void BeginPlay() override;
|
||||||
|
|
||||||
@ -48,8 +63,16 @@ protected:
|
|||||||
|
|
||||||
FRobotSettings RobotSettings = FRobotSettings();
|
FRobotSettings RobotSettings = FRobotSettings();
|
||||||
|
|
||||||
//virtual void EvaluateRobotPath();
|
ERobotInputType PathfindingInputType = ERobotInputType::None;
|
||||||
|
|
||||||
virtual void InterpolateSpeedValues(const float DeltaTime, const float Acceleration, const float Deceleration);
|
virtual void InterpolateSpeedValues(const float DeltaTime, const float Acceleration, const float Deceleration);
|
||||||
|
|
||||||
FVector2D CurrentSpeedValues = FVector2D::ZeroVector;
|
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;
|
||||||
};
|
};
|
@ -84,6 +84,9 @@ struct FRobotSplinePath
|
|||||||
UPROPERTY(BlueprintReadOnly, Category = "Robot Spline Path")
|
UPROPERTY(BlueprintReadOnly, Category = "Robot Spline Path")
|
||||||
FRuntimeFloatCurve SplinePathSpeedModifier = FRuntimeFloatCurve();
|
FRuntimeFloatCurve SplinePathSpeedModifier = FRuntimeFloatCurve();
|
||||||
|
|
||||||
|
UPROPERTY(BlueprintReadOnly, Category = "Robot Spline Path")
|
||||||
|
FVector PathfindingDestination = FVector::ZeroVector;
|
||||||
|
|
||||||
ALuckyRobotPawnBase* GetRobot() const { return Robot.Get(); }
|
ALuckyRobotPawnBase* GetRobot() const { return Robot.Get(); }
|
||||||
void GenerateSplinePath(ALuckyRobotPawnBase* InRobot, const FRobotNavPath& InNavPath);
|
void GenerateSplinePath(ALuckyRobotPawnBase* InRobot, const FRobotNavPath& InNavPath);
|
||||||
void RegenerateSplinePathValues();
|
void RegenerateSplinePathValues();
|
||||||
|
@ -158,6 +158,7 @@ public:
|
|||||||
void Look(const FInputActionValue& Value);
|
void Look(const FInputActionValue& Value);
|
||||||
|
|
||||||
void TogglePathfinding(const FInputActionValue& Value);
|
void TogglePathfinding(const FInputActionValue& Value);
|
||||||
|
void BeginPathfinding();
|
||||||
|
|
||||||
UFUNCTION(BlueprintPure, Category = "Lucky Robot Pawn")
|
UFUNCTION(BlueprintPure, Category = "Lucky Robot Pawn")
|
||||||
ERobotInputType GetCurrentInputType() const { return CurrentInputType; }
|
ERobotInputType GetCurrentInputType() const { return CurrentInputType; }
|
||||||
@ -186,12 +187,19 @@ public:
|
|||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input")
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input")
|
||||||
float TurnModifier = 1.f;
|
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:
|
protected:
|
||||||
virtual void BeginPlay() override;
|
virtual void BeginPlay() override;
|
||||||
|
|
||||||
bool HasMovementValue() const;
|
bool HasMovementValue() const;
|
||||||
bool HasTurnValue() const;
|
bool HasTurnValue() const;
|
||||||
bool IsPathfinding() const { return CurrentInputType == ERobotInputType::Pathfinding; }
|
|
||||||
|
|
||||||
void RemoveMujocoVolumeActor();
|
void RemoveMujocoVolumeActor();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user