在PlayerController中
变量
UPROPERTY(VisibleAnywhere,Category = "Input")
TObjectPtr<USplineComponent> Spline;
//是否在自动寻路
bool bAutoRunning = false;
//鼠标已按住时间
float FollowTime = 0.f;
//鼠标按住时间
UPROPERTY(EditAnywhere)
float HoldTimeToMove = 0.5f;
//到目的地距离
UPROPERTY(EditAnywhere)
float AutoRunningAcceptRadius = 50.f;
//目的地
FVector CachedDestination = FVector::Zero();
鼠标按下时
void ADiabloPlayerController::AbilityInputTagPressed()
{
bAutoRunning = false;
}
鼠标松开时,如果是点击事件,则按照路径点绘制样条线
void ADiabloPlayerController::AbilityInputTagReleased()
{
APawn* ControlledPawn = GetPawn();
if (FollowTime < HoldTimeToMove && ControlledPawn)
{
//寻踪玩家到目的地的路径
if (UNavigationPath* Path = UNavigationSystemV1::FindPathToLocationSynchronously(this,ControlledPawn->GetActorLocation(),CachedDestination))
{
Spline->ClearSplinePoints();
//路径上的点
TArray<FVector> Points = Path->PathPoints;
if (!Points.IsEmpty())
{
for (FVector PathPoint : Points)
{
//在样条线上加点
Spline->AddSplinePoint(PathPoint,ESplineCoordinateSpace::World);
DrawDebugSphere(GetWorld(),PathPoint,8.f,8,FColor::Green,false,5.f);
}
//最后点算做目的地
CachedDestination = Points.Last();
bAutoRunning = true;
}
}
}
FollowTime = 0;
}
按住鼠标时,朝着鼠标方向移动
void ADiabloPlayerController::AbilityInputTagHeld()
{
//按住时间累积
FollowTime += GetWorld()->GetDeltaSeconds();
//得到点击的目的地
FHitResult HitResult;
if (GetHitResultUnderCursor(ECC_Visibility,false,HitResult))
{
CachedDestination = HitResult.ImpactPoint;
}
APawn* ControlledPawn = GetPawn();
if (ControlledPawn)
{
//移动到目的地
FVector Direction = CachedDestination - ControlledPawn->GetActorLocation();
ControlledPawn->AddMovementInput(Direction);
}
}
Tick事件中
void ADiabloPlayerController::AutoRun()
{
if (!bAutoRunning)
{
return;
}
APawn* CharacterPawn = GetPawn();
if (CharacterPawn)
{
//找到玩家到样条线最近的点
FVector LocationOnSpline = Spline->FindLocationClosestToWorldLocation(CharacterPawn->GetActorLocation(),ESplineCoordinateSpace::World);
//获得样条线上该点的朝向
FVector Direction = Spline->FindDirectionClosestToWorldLocation(LocationOnSpline,ESplineCoordinateSpace::World);
CharacterPawn->AddMovementInput(Direction);
//计算到目的地距离
float Distance = (LocationOnSpline - CachedDestination).Length();
//到达目的地则停止寻路
if (Distance<= AutoRunningAcceptRadius)
{
bAutoRunning = false;
}
}
}