在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;
}
}
}