bool ACharacter::RestoreReplicatedMove(const FSimulatedRootMotionReplicatedMove& RootMotionRepMove) { UPrimitiveComponent* ServerBase = RootMotionRepMove.RootMotion.MovementBase; const FName ServerBaseBoneName = RootMotionRepMove.RootMotion.MovementBaseBoneName; // Relative Position if( RootMotionRepMove.RootMotion.bRelativePosition ) { bool bSuccess = false; if( MovementBaseUtility::UseRelativeLocation(ServerBase) ) { FVector BaseLocation; FQuat BaseRotation; MovementBaseUtility::GetMovementBaseTransform(ServerBase, ServerBaseBoneName, BaseLocation, BaseRotation); const FVector ServerLocation = BaseLocation + RootMotionRepMove.RootMotion.Location; FRotator ServerRotation; if (RootMotionRepMove.RootMotion.bRelativeRotation) { // Relative rotation ServerRotation = (FRotationMatrix(RootMotionRepMove.RootMotion.Rotation) * FQuatRotationTranslationMatrix(BaseRotation, FVector::ZeroVector)).Rotator(); } else { // Absolute rotation ServerRotation = RootMotionRepMove.RootMotion.Rotation; } UpdateSimulatedPosition(ServerLocation, ServerRotation); bSuccess = true; } // If we received local space position, but can't resolve parent, then move can't be used. :( if( !bSuccess ) { return false; } } // Absolute position else { UpdateSimulatedPosition(RootMotionRepMove.RootMotion.Location, RootMotionRepMove.RootMotion.Rotation); } SetBase( ServerBase, ServerBaseBoneName ); return true; }
bool ACharacter::RestoreReplicatedMove(const FSimulatedRootMotionReplicatedMove & RootMotionRepMove) { UPrimitiveComponent * ServerBase = RootMotionRepMove.RootMotion.MovementBase; // Relative Position if( RootMotionRepMove.RootMotion.bRelativePosition ) { bool bSuccess = false; if( MovementBaseUtility::UseRelativePosition(ServerBase) ) { const FVector ServerLocation = ServerBase->GetComponentLocation() + RootMotionRepMove.RootMotion.Location; const FRotator ServerRotation = (FRotationMatrix(RootMotionRepMove.RootMotion.Rotation) * FRotationMatrix(ServerBase->GetComponentRotation())).Rotator(); UpdateSimulatedPosition(ServerLocation, ServerRotation); bSuccess = true; } // If we received local space position, but can't resolve parent, then move can't be used. :( if( !bSuccess ) { return false; } } // Absolute position else { UpdateSimulatedPosition(RootMotionRepMove.RootMotion.Location, RootMotionRepMove.RootMotion.Rotation); } // Set base if( MovementBase != ServerBase ) { SetBase( ServerBase ); } // fixme laurent is this needed? if( CharacterMovement ) { CharacterMovement->bJustTeleported = false; } return true; }
void ACharacter::PostNetReceiveLocationAndRotation() { if( Role == ROLE_SimulatedProxy ) { // Don't change transform if using relative position (it should be nearly the same anyway, or base may be slightly out of sync) if (!ReplicatedBasedMovement.HasRelativeLocation()) { const FVector OldLocation = GetActorLocation(); UpdateSimulatedPosition(ReplicatedMovement.Location, ReplicatedMovement.Rotation); INetworkPredictionInterface* PredictionInterface = Cast<INetworkPredictionInterface>(GetMovementComponent()); if (PredictionInterface) { PredictionInterface->SmoothCorrection(OldLocation); } } } }
void ACharacter::PostNetReceiveLocation() { if( Role == ROLE_SimulatedProxy ) { // Don't change position if using relative position (it should be the same anyway) // TODO: actually we can't do this until SimulateMovement() actually calls UpdateBasedMovement(). //if (!RelativeMovement.HasRelativePosition()) { const FVector OldLocation = GetActorLocation(); UpdateSimulatedPosition(ReplicatedMovement.Location, ReplicatedMovement.Rotation); INetworkPredictionInterface* PredictionInterface = InterfaceCast<INetworkPredictionInterface>(GetMovementComponent()); if (PredictionInterface) { PredictionInterface->SmoothCorrection(OldLocation); } } } }