丝滑地更改角色朝向 (Change Character Rotation Smooth)

以下代码都与BindAxis一起使用
 
需要判断转身方向
  1. 使用 AddActorWorldRotation
  2. 判断转身方向
  3. Yaw的换算
  4. Rotation的处理(InterpTo函数 或者 自定义Delta)
    FHitResult TraceHitResult;
    GetHitResultUnderCursor(ECC_Visibility, true, TraceHitResult);
    FVector CursorLoc = TraceHitResult.Location;
    FVector PawnLoc = GetPawn()->GetActorLocation();
    FVector Direction = CursorLoc - PawnLoc;
    FRotator NewPawnRotation = Direction.Rotation();
    float PawnYaw = GetPawn()->GetActorRotation().Yaw;
    float NewPawnYaw = NewPawnRotation.Yaw;

    float NewPawnAngle = NewPawnYaw;
    float PawnAngle = PawnYaw;

    if (Value != 0.0f && PawnYaw != NewPawnYaw)
    {
        if (NewPawnYaw < 0)
        {
            NewPawnAngle = NewPawnYaw + 360.f;
        }

        if (PawnYaw < 0)
        {
            PawnAngle = PawnYaw + 360.f;
        }

        float TurnDelta = 360.0f * Value * GetWorld()->GetDeltaSeconds();
        float Angle = FMath::Abs(NewPawnAngle - PawnAngle);
        if (Angle > 180)
        {
            Angle = 360 - Angle;
        }

        if ((NewPawnAngle > PawnAngle && NewPawnAngle < PawnAngle + 180) || (PawnAngle > 180 && NewPawnAngle < PawnAngle - 180))
        {
            // 右转 
            if (Angle < TurnDelta)
            {
                PawnYaw = NewPawnYaw;
                GetPawn()->SetActorRotation(FRotator(0.f, PawnYaw, 0.f));
            }
            else
            {
                GetPawn()->AddActorWorldRotation(FRotator(0.f, TurnDelta, 0.f).Quaternion());
            }
        }
        else
        {
            // 左转
            if (Angle < TurnDelta)
            {
                PawnYaw = NewPawnYaw;
                GetPawn()->SetActorRotation(FRotator(0.f, PawnYaw, 0.f));
            }
            else
            {
                GetPawn()->AddActorWorldRotation(FRotator(0.f, -TurnDelta, 0.f).Quaternion());
            }
        }
    }
 
不需要判断转身方向
  1. Enable Use Controller Desired Rotation
  2. Set Controller Rotation
    FHitResult TraceHitResult;
    GetHitResultUnderCursor(ECC_Visibility, true, TraceHitResult);
    FVector CursorLoc = TraceHitResult.Location;
    FVector PawnLoc = GetPawn()->GetActorLocation();
    FVector Direction = CursorLoc - PawnLoc;
    FRotator NewPawnRotation = Direction.Rotation();
    float PawnYaw = GetPawn()->GetActorRotation().Yaw;
    float NewPawnYaw = NewPawnRotation.Yaw;

    float NewPawnAngle = NewPawnYaw;
    float PawnAngle = PawnYaw;

    if (Value != 0.0f && PawnYaw != NewPawnYaw)
    {
        SetControlRotation(FRotator(0.f, NewPawnYaw, 0.f));
    }

 

推荐使用第二个方法,不需要自己写更多逻辑,而且可以使AI转身更加顺滑 (解决方案来自:https://forums.unrealengine.com/development-discussion/blueprint-visual-scripting/1481068-ai-rotation-is-too-sharp)

posted @ 2020-10-08 18:48  当麻  阅读(280)  评论(0编辑  收藏  举报