UE5中实现鼠标点击移动


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

 

 
posted @ 2025-04-15 18:10  几个Ak  阅读(121)  评论(0)    收藏  举报