丝滑地更改角色朝向 (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 @   当麻  阅读(296)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示