void UCharacterMovementComponent::PhysFalling(float deltaTime, int32 Iterations)
{
else if ( Hit.bBlockingHit )
{
const FVector OldHitNormal = Hit.Normal;
const FVector OldHitImpactNormal = Hit.ImpactNormal;
FVector Delta = ComputeSlideVector(Adjusted, 1.f - Hit.Time, OldHitNormal, Hit);
// Move in deflected direction.
SafeMoveUpdatedComponent( Delta, PawnRotation, true, Hit);
if (Hit.bBlockingHit)
{
// hit second wall
FVector PreTwoWallDelta = Delta;
TwoWallAdjust(Delta, Hit, OldHitNormal);
在物理下落过程中,第一次碰撞后偏转移动过程,再次碰撞 hit seconde wall,调用TwoWallAdjust方法处理。
/**
* Compute a movement direction when contacting two surfaces.
* @param Delta: [In] Amount of move attempted before impact. [Out] Computed adjustment based on impacts.
* @param Hit: Impact from last attempted move
* @param OldHitNormal: Normal of impact before last attempted move
* @return Result in Delta that is the direction to move when contacting two surfaces.
*/
virtual void TwoWallAdjust(FVector &Delta, const FHitResult& Hit, const FVector &OldHitNormal) const;
void UMovementComponent::TwoWallAdjust(FVector& OutDelta, const FHitResult& Hit, const FVector& OldHitNormal) const
{
FVector Delta = OutDelta;
const FVector HitNormal = Hit.Normal;
if ((OldHitNormal | HitNormal) <= 0.f) //90 or less corner, so use cross product for direction
{
const FVector DesiredDir = Delta;
FVector NewDir = (HitNormal ^ OldHitNormal);
NewDir = NewDir.GetSafeNormal();
Delta = (Delta | NewDir) * (1.f - Hit.Time) * NewDir;
if ((DesiredDir | Delta) < 0.f)
{
Delta = -1.f * Delta;
}
}
else //adjust to new wall
{
const FVector DesiredDir = Delta;
Delta = ComputeSlideVector(Delta, 1.f - Hit.Time, HitNormal, Hit);
if ((Delta | DesiredDir) <= 0.f)
{
Delta = FVector::ZeroVector;
}
else if ( FMath::Abs((HitNormal | OldHitNormal) - 1.f) < KINDA_SMALL_NUMBER )
{
// we hit the same wall again even after adjusting to move along it the first time
// nudge away from it (this can happen due to precision issues)
Delta += HitNormal * 0.01f;
}
}
OutDelta = Delta;
}
两个墙面夹角<=90°(等价于两个法向量夹角>=90°,二者点积 <= 0),判断两个法向量叉乘的方向(向量)是否可移动。
两个墙面夹角>90°(等价于两个法向量夹角<90°,二者点积 > 0),判断是否可向第二个墙面移动。