Advertisement
Guest User

Untitled

a guest
Jan 23rd, 2017
535
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.79 KB | None | 0 0
  1. void UCharacterMovementComponent::PerformMovement(float DeltaSeconds)
  2. {
  3.     SCOPE_CYCLE_COUNTER(STAT_CharacterMovementPerformMovement);
  4.  
  5.     if (!HasValidData())
  6.     {
  7.         return;
  8.     }
  9.    
  10.     // no movement if we can't move, or if currently doing physical simulation on UpdatedComponent
  11.     if (MovementMode == MOVE_None || UpdatedComponent->Mobility != EComponentMobility::Movable || UpdatedComponent->IsSimulatingPhysics())
  12.     {
  13.         return;
  14.     }
  15.  
  16.     // Force floor update if we've moved outside of CharacterMovement since last update.
  17.     bForceNextFloorCheck |= (IsMovingOnGround() && UpdatedComponent->GetComponentLocation() != LastUpdateLocation);
  18.  
  19.     // Update saved LastPreAdditiveVelocity with any external changes to character Velocity that happened since last update (jumps, knockbacks, etc.)
  20.     if( CurrentRootMotion.HasAdditiveVelocity() )
  21.     {
  22.         CurrentRootMotion.LastPreAdditiveVelocity += (Velocity-LastUpdateVelocity);
  23.     }
  24.  
  25.     FVector OldVelocity;
  26.     FVector OldLocation;
  27.  
  28.     // Scoped updates can improve performance of multiple MoveComponent calls.
  29.     {
  30.         FScopedMovementUpdate ScopedMovementUpdate(UpdatedComponent, bEnableScopedMovementUpdates ? EScopedUpdate::DeferredUpdates : EScopedUpdate::ImmediateUpdates);
  31.  
  32.         MaybeUpdateBasedMovement(DeltaSeconds);
  33.  
  34.         OldVelocity = Velocity;
  35.         OldLocation = UpdatedComponent->GetComponentLocation();
  36.  
  37.         ApplyAccumulatedForces(DeltaSeconds);
  38.  
  39.         // Check for a change in crouch state. Players toggle crouch by changing bWantsToCrouch.
  40.         const bool bAllowedToCrouch = CanCrouchInCurrentState();
  41.         if ((!bAllowedToCrouch || !bWantsToCrouch) && IsCrouching())
  42.         {
  43.             UnCrouch(false);
  44.         }
  45.         else if (bWantsToCrouch && bAllowedToCrouch && !IsCrouching())
  46.         {
  47.             Crouch(false);
  48.         }
  49.  
  50.         if (MovementMode == MOVE_NavWalking && bWantsToLeaveNavWalking)
  51.         {
  52.             TryToLeaveNavWalking();
  53.         }
  54.  
  55.         // Character::LaunchCharacter() has been deferred until now.
  56.         HandlePendingLaunch();
  57.  
  58.         // Prepare Root Motion (generate/accumulate from root motion sources to be used later)
  59.         if( HasRootMotionSources() && !CharacterOwner->bClientUpdating && !CharacterOwner->bServerMoveIgnoreRootMotion)
  60.         {
  61.             // Animation root motion - If using animation RootMotion, tick animations before running physics.
  62.             if( CharacterOwner->IsPlayingRootMotion() && CharacterOwner->GetMesh() )
  63.             {
  64.                 TickCharacterPose(DeltaSeconds);
  65.  
  66.                 // Make sure animation didn't trigger an event that destroyed us
  67.                 if (!HasValidData())
  68.                 {
  69.                     return;
  70.                 }
  71.  
  72.                 // For local human clients, save off root motion data so it can be used by movement networking code.
  73.                 if( CharacterOwner->IsLocallyControlled() && (CharacterOwner->Role == ROLE_AutonomousProxy) && CharacterOwner->IsPlayingNetworkedRootMotionMontage() )
  74.                 {
  75.                     CharacterOwner->ClientRootMotionParams = RootMotionParams;
  76.                 }
  77.             }
  78.  
  79.             // Generates root motion to be used this frame from sources other than animation
  80.             {
  81.                 SCOPE_CYCLE_COUNTER(STAT_CharacterMovementRootMotionSourceCalculate);
  82.                 CurrentRootMotion.PrepareRootMotion(DeltaSeconds, *CharacterOwner, *this, true);
  83.             }
  84.  
  85.             // For local human clients, save off root motion data so it can be used by movement networking code.
  86.             if( CharacterOwner->IsLocallyControlled() && (CharacterOwner->Role == ROLE_AutonomousProxy) )
  87.             {
  88.                 CharacterOwner->SavedRootMotion = CurrentRootMotion;
  89.             }
  90.         }
  91.  
  92.         // Apply Root Motion to Velocity
  93.         if( CurrentRootMotion.HasOverrideVelocity() || HasAnimRootMotion() )
  94.         {
  95.             // Animation root motion overrides Velocity and currently doesn't allow any other root motion sources
  96.             if( HasAnimRootMotion() )
  97.             {
  98.                 // Convert to world space (animation root motion is always local)
  99.                 USkeletalMeshComponent * SkelMeshComp = CharacterOwner->GetMesh();
  100.                 if( SkelMeshComp )
  101.                 {
  102.                     // Convert Local Space Root Motion to world space. Do it right before used by physics to make sure we use up to date transforms, as translation is relative to rotation.
  103.                     RootMotionParams.Set( SkelMeshComp->ConvertLocalRootMotionToWorld(RootMotionParams.GetRootMotionTransform()) );
  104.                 }
  105.  
  106.                 // Then turn root motion to velocity to be used by various physics modes.
  107.                 if( DeltaSeconds > 0.f )
  108.                 {
  109.                     AnimRootMotionVelocity = CalcAnimRootMotionVelocity(RootMotionParams.GetRootMotionTransform().GetTranslation(), DeltaSeconds, Velocity);
  110.                     Velocity = ConstrainAnimRootMotionVelocity(AnimRootMotionVelocity, Velocity);
  111.                 }
  112.                
  113.                 UE_LOG(LogRootMotion, Log,  TEXT("PerformMovement WorldSpaceRootMotion Translation: %s, Rotation: %s, Actor Facing: %s, Velocity: %s")
  114.                     , *RootMotionParams.GetRootMotionTransform().GetTranslation().ToCompactString()
  115.                     , *RootMotionParams.GetRootMotionTransform().GetRotation().Rotator().ToCompactString()
  116.                     , *CharacterOwner->GetActorForwardVector().ToCompactString()
  117.                     , *Velocity.ToCompactString()
  118.                     );
  119.             }
  120.             else
  121.             {
  122.                 // We don't have animation root motion so we apply other sources
  123.                 if( DeltaSeconds > 0.f )
  124.                 {
  125.                     SCOPE_CYCLE_COUNTER(STAT_CharacterMovementRootMotionSourceApply);
  126.                     FVector NewVelocity = Velocity;
  127.                     CurrentRootMotion.AccumulateOverrideRootMotionVelocity(DeltaSeconds, *CharacterOwner, *this, NewVelocity);
  128.                     Velocity = NewVelocity;
  129.                 }
  130.             }
  131.         }
  132.  
  133.         // NaN tracking
  134.         checkCode(ensureMsgf(!Velocity.ContainsNaN(), TEXT("UCharacterMovementComponent::PerformMovement: Velocity contains NaN (%s)\n%s"), *GetPathNameSafe(this), *Velocity.ToString()));
  135.  
  136.         // Clear jump input now, to allow movement events to trigger it for next update.
  137.         CharacterOwner->ClearJumpInput();
  138.  
  139.         // change position
  140.         StartNewPhysics(DeltaSeconds, 0);
  141.  
  142.         if (!HasValidData())
  143.         {
  144.             return;
  145.         }
  146.  
  147.         // uncrouch if no longer allowed to be crouched
  148.         if (IsCrouching() && !CanCrouchInCurrentState())
  149.         {
  150.             UnCrouch(false);
  151.         }
  152.  
  153.         if (!HasAnimRootMotion() && !CharacterOwner->IsMatineeControlled())
  154.         {
  155.             PhysicsRotation(DeltaSeconds);
  156.         }
  157.  
  158.         // Apply Root Motion rotation after movement is complete.
  159.         if( HasAnimRootMotion() )
  160.         {
  161.             const FQuat OldActorRotationQuat = UpdatedComponent->GetComponentQuat();
  162.             const FQuat RootMotionRotationQuat = RootMotionParams.GetRootMotionTransform().GetRotation();
  163.             if( !RootMotionRotationQuat.IsIdentity() )
  164.             {
  165.                 const FQuat NewActorRotationQuat = RootMotionRotationQuat * OldActorRotationQuat;
  166.                 MoveUpdatedComponent(FVector::ZeroVector, NewActorRotationQuat, true);
  167.             }
  168.  
  169. #if !(UE_BUILD_SHIPPING)
  170.             // debug
  171.             if (false)
  172.             {
  173.                 const FRotator OldActorRotation = OldActorRotationQuat.Rotator();
  174.                 const FVector ResultingLocation = UpdatedComponent->GetComponentLocation();
  175.                 const FRotator ResultingRotation = UpdatedComponent->GetComponentRotation();
  176.  
  177.                 // Show current position
  178.                 DrawDebugCoordinateSystem(GetWorld(), CharacterOwner->GetMesh()->GetComponentLocation() + FVector(0,0,1), ResultingRotation, 50.f, false);
  179.  
  180.                 // Show resulting delta move.
  181.                 DrawDebugLine(GetWorld(), OldLocation, ResultingLocation, FColor::Red, true, 10.f);
  182.  
  183.                 // Log details.
  184.                 UE_LOG(LogRootMotion, Warning,  TEXT("PerformMovement Resulting DeltaMove Translation: %s, Rotation: %s, MovementBase: %s"),
  185.                     *(ResultingLocation - OldLocation).ToCompactString(), *(ResultingRotation - OldActorRotation).GetNormalized().ToCompactString(), *GetNameSafe(CharacterOwner->GetMovementBase()) );
  186.  
  187.                 const FVector RMTranslation = RootMotionParams.GetRootMotionTransform().GetTranslation();
  188.                 const FRotator RMRotation = RootMotionParams.GetRootMotionTransform().GetRotation().Rotator();
  189.                 UE_LOG(LogRootMotion, Warning,  TEXT("PerformMovement Resulting DeltaError Translation: %s, Rotation: %s"),
  190.                     *(ResultingLocation - OldLocation - RMTranslation).ToCompactString(), *(ResultingRotation - OldActorRotation - RMRotation).GetNormalized().ToCompactString() );
  191.             }
  192. #endif // !(UE_BUILD_SHIPPING)
  193.  
  194.             // Root Motion has been used, clear
  195.             RootMotionParams.Clear();
  196.         }
  197.  
  198.         // consume path following requested velocity
  199.         bHasRequestedVelocity = false;
  200.  
  201.         OnMovementUpdated(DeltaSeconds, OldLocation, OldVelocity);
  202.     } // End scoped movement update
  203.  
  204.     // Call external post-movement events. These happen after the scoped movement completes in case the events want to use the current state of overlaps etc.
  205.     CallMovementUpdateDelegate(DeltaSeconds, OldLocation, OldVelocity);
  206.  
  207.     MaybeSaveBaseLocation();
  208.     UpdateComponentVelocity();
  209.  
  210.     const bool bHasAuthority = CharacterOwner && CharacterOwner->HasAuthority();
  211.  
  212.     // If we move we want to avoid a long delay before replication catches up to notice this change, especially if it's throttling our rate.
  213.     if (bHasAuthority && UNetDriver::IsAdaptiveNetUpdateFrequencyEnabled() && UpdatedComponent)
  214.     {
  215.         const UWorld* MyWorld = GetWorld();
  216.         if (MyWorld && MyWorld->GetTimeSeconds() <= CharacterOwner->NetUpdateTime)
  217.         {
  218.             UNetDriver* NetDriver = MyWorld->GetNetDriver();
  219.             if (NetDriver && NetDriver->IsServer())
  220.             {
  221.                 FNetworkObjectInfo* NetActor = NetDriver->GetNetworkActor(CharacterOwner);
  222.                 if (NetActor && NetDriver->IsNetworkActorUpdateFrequencyThrottled(*NetActor))
  223.                 {
  224.                     if (ShouldCancelAdaptiveReplication())
  225.                     {
  226.                         NetDriver->CancelAdaptiveReplication(*NetActor);
  227.                     }
  228.                 }
  229.             }
  230.         }
  231.     }
  232.  
  233.     if (bHasAuthority && UpdatedComponent && !IsNetMode(NM_Client))
  234.     {
  235.         const bool bLocationChanged = (UpdatedComponent->GetComponentLocation() != LastUpdateLocation);
  236.         const bool bRotationChanged = (UpdatedComponent->GetComponentQuat() != LastUpdateRotation);
  237.         if (bLocationChanged || bRotationChanged)
  238.         {
  239.             const UWorld* MyWorld = GetWorld();
  240.             ServerLastTransformUpdateTimeStamp = MyWorld ? MyWorld->GetTimeSeconds() : 0.f;
  241.         }
  242.     }
  243.  
  244.     LastUpdateLocation = UpdatedComponent ? UpdatedComponent->GetComponentLocation() : FVector::ZeroVector;
  245.     LastUpdateRotation = UpdatedComponent ? UpdatedComponent->GetComponentQuat() : FQuat::Identity;
  246.     LastUpdateVelocity = Velocity;
  247. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement