人物Rotation浅析

概述

概述: FaceRotation表明由程序自定义接管. PhysicsRotation表明通过Lerp形式按照一定速率转向目标方向(速度方向或者Controller朝向). 并且是速度位置计算完成后, 才设置朝向. 

  1. bUseControllerRotationYaw+bUseControllerRotationPitch+bUseControllerRotationRoll, bOrientRotationToMovement, bUseControllerDesiredRotation三者互斥.
  2. 如果同时开启, bOrientRotationToMovement优先级高于bUseControllerDesiredRotation
  3. FaceRotation表明朝向有程序接管, 直接控制.
  4. PhysicsRotation表示根据目标朝向, 平滑转动. 目标朝向由bOrientRotationToMovementbUseControllerDesiredRotation确定. 速率由RotationRate决定.

关键数据

UCharacterMovementComponent

bAllowPhysicsRotationDuringAnimRootMotion

1
2
// 在执行RootMotion期间, 是否允许执行PhysicsRotation
uint8 bAllowPhysicsRotationDuringAnimRootMotion : 1;

默认情况下, RootMotion期间, 不允许执行PhysicsRotation, 原因为动画直接控制人物朝向, 不需要在进行调整.

除非指定允许执行PhysicsRotation, 否则RootMotion期间, 不允许执行PhysicsRotation.

bUseControllerDesiredRotation

1
2
3
4
5
6
7
// If true, smoothly rotate the Character toward the Controller's desired rotation (typically Controller->ControlRotation), 
// using RotationRate as the rate of rotation change. Overridden by OrientRotationToMovement.
// Normally you will want to make sure that other settings are cleared, such as bUseControllerRotationYaw on the Character.
// 如果设置为true, 则将人物朝向调整到和Controller.ControlRotation一致.
// 使用RotationRate作为旋转的速率. 优先判断bOrientRotationToMovement, 然后在判断bUseControllerDesiredRotation
// 该变量与其他变量互斥, 例如Character身上的bUseControllerRotationYaw
uint8 bUseControllerDesiredRotation:1;

如果启用该功能, 则人物朝向会平滑朝向Controller.ControlledRotation.

该字段(bUseControllerDesiredRotation)和APawnbUseControllerRotationYaw+bUseControllerRotationPitch+bUseControllerRotationRoll是互斥的. 二者只能选其一, 否则可能会出现抖动(一般情况下不会).

当Base更新的时候, 也需要调整朝向.

bOrientRotationToMovement

1
2
3
4
5
6
7
// If true, rotate the Character toward the direction of acceleration, 
// using RotationRate as the rate of rotation change. Overrides UseControllerDesiredRotation.
// Normally you will want to make sure that other settings are cleared, such as bUseControllerRotationYaw on the Character.
// 该变量和其他变量互斥, 例如bUseControllerRotationYaw等
// 如果设置为true, 表示Character将Smooth朝着移动方向转动. 使用RotationRate作为Delta.
// 优先判断bOrientRotationToMovement, 然后在判断bUseControllerDesiredRotation
uint8 bOrientRotationToMovement:1;

该变量表示Character将Smooth朝着移动方向转动. 使用RotationRate作为Delta.

  1. base更新的时候, 刷新Rotation

  1. 平滑处理

RotationRate

1
2
3
// Change in rotation per second, used when UseControllerDesiredRotation or OrientRotationToMovement are true. 
// Set a negative value for infinite rotation rate and instant turns. */
FRotator RotationRate;

旋转速率, 根据该属性+Delta时间, 计算每帧旋转角度.

函数ComputeOrientToMovementRotation

1
2
3
4
5
6
7
8
9
// Compute a target rotation based on current movement. Used by PhysicsRotation() when bOrientRotationToMovement is true.
// Default implementation targets a rotation based on Acceleration.
//
// @param CurrentRotation - Current rotation of the Character
// @param DeltaTime - Time slice for this movement
// @param DeltaRotation - Proposed rotation change based simply on DeltaTime * RotationRate
//
// @return The target rotation given current movement.
virtual FRotator ComputeOrientToMovementRotation(const FRotator& CurrentRotation, float DeltaTime, FRotator& DeltaRotation) const;

计算开启bOrientRotationToMovement后的目标朝向.

  1. 如果加速度不为0, 则使用加速度方向作为目标朝向.
  2. 如果加速度为0, 则使用速度方向作为目标朝向.
  3. 否则, 使用当前朝向作为目标朝向.

APawn

bUseControllerRotationYaw

1
2
3
// If true, this Pawn's yaw will be updated to match the Controller's ControlRotation yaw, if controlled by a PlayerController.
// 如果设置为true, pawn的rotation会更新到匹配Controller.ControlRotation.Yaw.
uint32 bUseControllerRotationYaw:1;

bUseControllerRotationPitch

1
2
3
4
// If true, this Pawn's pitch will be updated to match the Controller's ControlRotation pitch, 
// if controlled by a PlayerController.
// 如果设置为true, pawn的rotation会更新到匹配Controller.ControlRotation.pitch.
uint32 bUseControllerRotationPitch:1;

bUseControllerRotationRoll

1
2
3
4
// If true, this Pawn's roll will be updated to match the Controller's ControlRotation roll, 
// if controlled by a PlayerController.
// 如果设置为true, pawn的rotation会更新到匹配Controller.ControlRotation.roll.
uint32 bUseControllerRotationRoll:1;

函数FaceRotation

1
2
3
4
// Updates Pawn's rotation to the given rotation, assumed to be the Controller's ControlRotation.
// Respects the bUseControllerRotation* settings.
// 朝向给定Rotation, 一般情况下用于需要指定的朝向.
virtual void FaceRotation(FRotator NewControlRotation, float DeltaTime = 0.f);

根据给定Rotation, 直接设置Character朝向. 即表示它的朝向受Controller的控制. 最直观的表现是它不受到速度,加速度的影响, 有Controller直接设置.

  1. 在DS强制设置客户端朝向的时候:ClientSetRotation_Implementation

  1. 无法忽略base朝向的时候(bIgnoreBaseRotation), 即站在可移动物体上, 要根据base朝向调整人物朝向.

  1. 移动合包的时候, 也需要重新设置人物朝向.

  1. PlayerController更新ControlledRotation时候APlayerController::UpdateRotation

Rotation流程

关键函数UCharacterMovementComponent::PhysicsRotation. 核心:

  1. 根据DeltaTime+RotationRate计算DeltaRot
  2. 根据类型计算TargetRotation
  3. 计算FixTurn

APawn.FaceRotationUCharacterMovementComponent.PhysicsRotation的区别

指定: FaceRotation是指定朝向, 每帧自己算, 然后直接设置朝向. 如果需要平滑处理, 则需要自己在逻辑中添加.

平滑: PhysicsRotation是计算目标Rotation, 然后根据转速(RotationRate)平滑转过去.