예제 #1
0
void ACharacter::OnRep_ReplicatedBasedMovement()
{
    if (Role != ROLE_SimulatedProxy)
    {
        return;
    }

    // Skip base updates while playing root motion, it is handled inside of OnRep_RootMotion
    if (IsPlayingNetworkedRootMotionMontage())
    {
        return;
    }

    TGuardValue<bool> bInBaseReplicationGuard(bInBaseReplication, true);

    const bool bBaseChanged = (BasedMovement.MovementBase != ReplicatedBasedMovement.MovementBase || BasedMovement.BoneName != ReplicatedBasedMovement.BoneName);
    if (bBaseChanged)
    {
        // Even though we will copy the replicated based movement info, we need to use SetBase() to set up tick dependencies and trigger notifications.
        SetBase(ReplicatedBasedMovement.MovementBase, ReplicatedBasedMovement.BoneName);
    }

    // Make sure to use the values of relative location/rotation etc from the server.
    BasedMovement = ReplicatedBasedMovement;

    if (ReplicatedBasedMovement.HasRelativeLocation())
    {
        // Update transform relative to movement base
        const FVector OldLocation = GetActorLocation();
        const FQuat OldRotation = GetActorQuat();
        MovementBaseUtility::GetMovementBaseTransform(ReplicatedBasedMovement.MovementBase, ReplicatedBasedMovement.BoneName, CharacterMovement->OldBaseLocation, CharacterMovement->OldBaseQuat);
        const FVector NewLocation = CharacterMovement->OldBaseLocation + ReplicatedBasedMovement.Location;

        if (ReplicatedBasedMovement.HasRelativeRotation())
        {
            // Relative location, relative rotation
            FRotator NewRotation = (FRotationMatrix(ReplicatedBasedMovement.Rotation) * FQuatRotationMatrix(CharacterMovement->OldBaseQuat)).Rotator();

            // TODO: need a better way to not assume we only use Yaw.
            NewRotation.Pitch = 0.f;
            NewRotation.Roll = 0.f;

            SetActorLocationAndRotation(NewLocation, NewRotation);
        }
        else
        {
            // Relative location, absolute rotation
            SetActorLocationAndRotation(NewLocation, ReplicatedBasedMovement.Rotation);
        }

        // When position or base changes, movement mode will need to be updated. This assumes rotation changes don't affect that.
        CharacterMovement->bJustTeleported |= (bBaseChanged || GetActorLocation() != OldLocation);

        INetworkPredictionInterface* PredictionInterface = Cast<INetworkPredictionInterface>(GetMovementComponent());
        if (PredictionInterface)
        {
            PredictionInterface->SmoothCorrection(OldLocation, OldRotation);
        }
    }
}
예제 #2
0
void ACharacter::UpdateSimulatedPosition(const FVector& NewLocation, const FRotator& NewRotation)
{
    // Always consider Location as changed if we were spawned this tick as in that case our replicated Location was set as part of spawning, before PreNetReceive()
    if( (NewLocation != GetActorLocation()) || (CreationTime == GetWorld()->TimeSeconds) )
    {
        FVector FinalLocation = NewLocation;

        // Only need to check for encroachment when teleported without any velocity.
        // Normal movement pops the character out of geometry anyway, no use doing it before and after (with different rules).
        bSimGravityDisabled = false;
        if (CharacterMovement->Velocity.IsZero())
        {
            if (GetWorld()->EncroachingBlockingGeometry(this, NewLocation, NewRotation))
            {
                bSimGravityDisabled = true;
            }
        }

        // Don't use TeleportTo(), that clears our base.
        SetActorLocationAndRotation(FinalLocation, NewRotation, false);
        CharacterMovement->bJustTeleported = true;
    }
    else if( NewRotation != GetActorRotation() )
    {
        GetRootComponent()->MoveComponent(FVector::ZeroVector, NewRotation, false);
    }
}
예제 #3
0
void ACharacter::UpdateSimulatedPosition(const FVector & NewLocation, const FRotator & NewRotation)
{
	// Always consider Location as changed if we were spawned this tick as in that case our replicated Location was set as part of spawning, before PreNetReceive()
	if( (NewLocation != GetActorLocation()) || (CreationTime == GetWorld()->TimeSeconds) )
	{
		FVector FinalLocation = NewLocation;
		if( GetWorld()->EncroachingBlockingGeometry(this, NewLocation, NewRotation) )
		{
			bSimGravityDisabled = true;
		}
		else
		{
			// Correction to make sure pawn doesn't penetrate floor after replication rounding
			FinalLocation.Z += 0.01f;
			bSimGravityDisabled = false;
		}
		
		// Don't use TeleportTo(), that clears our base.
		SetActorLocationAndRotation(FinalLocation, NewRotation, false);
	}
	else if( NewRotation != GetActorRotation() )
	{
		GetRootComponent()->MoveComponent(FVector::ZeroVector, NewRotation, false);
	}
}
예제 #4
0
void AActor::PostNetReceiveLocationAndRotation()
{
	if( RootComponent && RootComponent->IsRegistered() && (ReplicatedMovement.Location != GetActorLocation() || ReplicatedMovement.Rotation != GetActorRotation()) )
	{
		SetActorLocationAndRotation(ReplicatedMovement.Location, ReplicatedMovement.Rotation, /*bSweep=*/ false);
	}
}
예제 #5
0
void ACharacter::PostNetReceiveBase()
{	
	const bool bBaseChanged = (RelativeMovement.MovementBase != MovementBase);
	if (bBaseChanged)
	{
		SetBase(RelativeMovement.MovementBase);
	}

	if (RelativeMovement.HasRelativePosition())
	{
		if (bBaseChanged || (RelativeMovement.Location != SavedRelativeLocation) || (RelativeMovement.Rotation != SavedRelativeRotation))
		{
			const FVector OldLocation = GetActorLocation();
			const FRotator NewRotation = (FRotationMatrix(RelativeMovement.Rotation) * FRotationMatrix(MovementBase->GetComponentRotation())).Rotator();
			SetActorLocationAndRotation( MovementBase->GetComponentLocation() + RelativeMovement.Location, NewRotation, false);

			INetworkPredictionInterface* PredictionInterface = InterfaceCast<INetworkPredictionInterface>(GetMovementComponent());
			if (PredictionInterface)
			{
				PredictionInterface->SmoothCorrection(OldLocation);
			}
		}
	}

	if ( CharacterMovement )
	{
		CharacterMovement->bJustTeleported = false;
	}
}
예제 #6
0
void ABrush::InitPosRotScale()
{
	check(BrushComponent);

	SetActorLocationAndRotation(FVector::ZeroVector, FQuat::Identity, false);
	SetPivotOffset( FVector::ZeroVector );
}
void AMagicBattleSoccerBall::MoveWithPossessor()
{
    // This is used to roll the ball while a possessor owns it. The angle is a function of how far the ball has travelled.
    NegDistanceTravelled += Possessor->GetVelocity().Size() * -0.015f;

    // All platforms should move the same way if there is a possessor.
    SetActorLocationAndRotation(Possessor->GetActorLocation() + Possessor->GetActorForwardVector() * DISTANCE_IN_FRONT_OF_POSSESSOR + FVector(0.0f, 0.0f, POSSESSOR_Z_OFFSET),
                                FRotator(NegDistanceTravelled, Possessor->GetActorRotation().Yaw, 0.0f));
}
void AGameplayAbilityTargetActor_Trace::Tick(float DeltaSeconds)
{
	// very temp - do a mostly hardcoded trace from the source actor
	if (SourceActor)
	{
		FHitResult HitResult = PerformTrace(SourceActor);
		FVector EndPoint = HitResult.Component.IsValid() ? HitResult.ImpactPoint : HitResult.TraceEnd;

		if (bDebug)
		{
			DrawDebugLine(GetWorld(), SourceActor->GetActorLocation(), EndPoint, FColor::Green, false);
			DrawDebugSphere(GetWorld(), EndPoint, 16, 10, FColor::Green, false);
		}

		SetActorLocationAndRotation(EndPoint, SourceActor->GetActorRotation());
	}
}
예제 #9
0
void ABrush::CopyPosRotScaleFrom( ABrush* Other )
{
	check(BrushComponent);
	check(Other);
	check(Other->BrushComponent);

	SetActorLocationAndRotation(Other->GetActorLocation(), Other->GetActorRotation(), false);
	if( GetRootComponent() != NULL )
	{
		SetPivotOffset(Other->GetPivotOffset());
	}

	if(Brush)
	{
		Brush->BuildBound();
	}

	ReregisterAllComponents();
}
예제 #10
0
void APawn::PostNetReceiveLocationAndRotation()
{
	// always consider Location as changed if we were spawned this tick as in that case our replicated Location was set as part of spawning, before PreNetReceive()
	if( (ReplicatedMovement.Location == GetActorLocation() && ReplicatedMovement.Rotation == GetActorRotation()) && (CreationTime != GetWorld()->TimeSeconds) )
	{
		return;
	}

	if( Role == ROLE_SimulatedProxy )
	{
		// Correction to make sure pawn doesn't penetrate floor after replication rounding
		ReplicatedMovement.Location.Z += 0.01f;

		const FVector OldLocation = GetActorLocation();
		const FQuat OldRotation = GetActorQuat();
		SetActorLocationAndRotation(ReplicatedMovement.Location, ReplicatedMovement.Rotation, /*bSweep=*/ false);

		INetworkPredictionInterface* PredictionInterface = Cast<INetworkPredictionInterface>(GetMovementComponent());
		if (PredictionInterface)
		{
			PredictionInterface->SmoothCorrection(OldLocation, OldRotation, ReplicatedMovement.Location, ReplicatedMovement.Rotation.Quaternion());
		}
	}
}
예제 #11
0
void APlayerCameraManager::UpdateViewTarget(FTViewTarget& OutVT, float DeltaTime)
{
	// Don't update outgoing viewtarget during an interpolation 
	if ((PendingViewTarget.Target != NULL) && BlendParams.bLockOutgoing && OutVT.Equal(ViewTarget))
	{
		return;
	}

	// store previous POV, in case we need it later
	FMinimalViewInfo OrigPOV = OutVT.POV;

	//@TODO: CAMERA: Should probably reset the view target POV fully here
	OutVT.POV.FOV = DefaultFOV;
	OutVT.POV.OrthoWidth = DefaultOrthoWidth;
	OutVT.POV.bConstrainAspectRatio = false;
	OutVT.POV.bUseFieldOfViewForLOD = true;
	OutVT.POV.ProjectionMode = bIsOrthographic ? ECameraProjectionMode::Orthographic : ECameraProjectionMode::Perspective;
	OutVT.POV.PostProcessSettings.SetBaseValues();
	OutVT.POV.PostProcessBlendWeight = 1.0f;


	bool bDoNotApplyModifiers = false;

	if (ACameraActor* CamActor = Cast<ACameraActor>(OutVT.Target))
	{
		// Viewing through a camera actor.
		CamActor->GetCameraComponent()->GetCameraView(DeltaTime, OutVT.POV);
	}
	else
	{

		static const FName NAME_Fixed = FName(TEXT("Fixed"));
		static const FName NAME_ThirdPerson = FName(TEXT("ThirdPerson"));
		static const FName NAME_FreeCam = FName(TEXT("FreeCam"));
		static const FName NAME_FreeCam_Default = FName(TEXT("FreeCam_Default"));
		static const FName NAME_FirstPerson = FName(TEXT("FirstPerson"));

		if (CameraStyle == NAME_Fixed)
		{
			// do not update, keep previous camera position by restoring
			// saved POV, in case CalcCamera changes it but still returns false
			OutVT.POV = OrigPOV;

			// don't apply modifiers when using this debug camera mode
			bDoNotApplyModifiers = true;
		}
		else if (CameraStyle == NAME_ThirdPerson || CameraStyle == NAME_FreeCam || CameraStyle == NAME_FreeCam_Default)
		{
			// Simple third person view implementation
			FVector Loc = OutVT.Target->GetActorLocation();
			FRotator Rotator = OutVT.Target->GetActorRotation();

			if (OutVT.Target == PCOwner)
			{
				Loc = PCOwner->GetFocalLocation();
			}

			// Take into account Mesh Translation so it takes into account the PostProcessing we do there.
			// @fixme, can crash in certain BP cases where default mesh is null
//			APawn* TPawn = Cast<APawn>(OutVT.Target);
// 			if ((TPawn != NULL) && (TPawn->Mesh != NULL))
// 			{
// 				Loc += FQuatRotationMatrix(OutVT.Target->GetActorQuat()).TransformVector(TPawn->Mesh->RelativeLocation - GetDefault<APawn>(TPawn->GetClass())->Mesh->RelativeLocation);
// 			}

			//OutVT.Target.GetActorEyesViewPoint(Loc, Rot);
			if( CameraStyle == NAME_FreeCam || CameraStyle == NAME_FreeCam_Default )
			{
				Rotator = PCOwner->GetControlRotation();
			}

			FVector Pos = Loc + FRotationMatrix(Rotator).TransformVector(FreeCamOffset) - Rotator.Vector() * FreeCamDistance;
			FCollisionQueryParams BoxParams(NAME_FreeCam, false, this);
			BoxParams.AddIgnoredActor(OutVT.Target);
			FHitResult Result;

			GetWorld()->SweepSingleByChannel(Result, Loc, Pos, FQuat::Identity, ECC_Camera, FCollisionShape::MakeBox(FVector(12.f)), BoxParams);
			OutVT.POV.Location = !Result.bBlockingHit ? Pos : Result.Location;
			OutVT.POV.Rotation = Rotator;

			// don't apply modifiers when using this debug camera mode
			bDoNotApplyModifiers = true;
		}
		else if (CameraStyle == NAME_FirstPerson)
		{
			// Simple first person, view through viewtarget's 'eyes'
			OutVT.Target->GetActorEyesViewPoint(OutVT.POV.Location, OutVT.POV.Rotation);
	
			// don't apply modifiers when using this debug camera mode
			bDoNotApplyModifiers = true;
		}
		else
		{
			UpdateViewTargetInternal(OutVT, DeltaTime);
		}
	}

	if (!bDoNotApplyModifiers || bAlwaysApplyModifiers)
	{
		// Apply camera modifiers at the end (view shakes for example)
		ApplyCameraModifiers(DeltaTime, OutVT.POV);
	}

	if (bFollowHmdOrientation)
	{
		if (GEngine->HMDDevice.IsValid() && GEngine->HMDDevice->IsHeadTrackingAllowed())
		{
			GEngine->HMDDevice->UpdatePlayerCameraRotation(this, OutVT.POV);
		}
	}

	// Synchronize the actor with the view target results
	SetActorLocationAndRotation(OutVT.POV.Location, OutVT.POV.Rotation, false);

	UpdateCameraLensEffects(OutVT);
}
예제 #12
0
void AController::SetInitialLocationAndRotation(const FVector& NewLocation, const FRotator& NewRotation)
{
	SetActorLocationAndRotation(NewLocation, NewRotation);
	SetControlRotation(NewRotation);
}
/** Simulates the free movement of the ball based on proxy states */
void AMagicBattleSoccerBall::ClientSimulateFreeMovingBall()
{
    AMagicBattleSoccerPlayerController* MyPC = Cast<AMagicBattleSoccerPlayerController>(UGameplayStatics::GetPlayerController(GetWorld(), 0));
    if (nullptr == MyPC || !MyPC->IsNetworkTimeValid() || 0 == proxyStateCount)
    {
        // We don't know yet know what the time is on the server yet so the timestamps
        // of the proxy states mean nothing; that or we simply don't have any proxy
        // states yet. Don't do any interpolation.
        SetActorLocationAndRotation(ServerPhysicsState.pos, ServerPhysicsState.rot);
    }
    else
    {
        uint64 interpolationBackTime = 100;
        uint64 extrapolationLimit = 500;

        // This is the target playback time of the rigid body
        uint64 interpolationTime = MyPC->GetNetworkTime() - interpolationBackTime;

        // Use interpolation if the target playback time is present in the buffer
        if (proxyStates[0].timestamp > interpolationTime)
        {
            // Go through buffer and find correct state to play back
            for (int i=0; i<proxyStateCount; i++)
            {
                if (proxyStates[i].timestamp <= interpolationTime || i == proxyStateCount-1)
                {
                    // The state one slot newer (<100ms) than the best playback state
                    FSmoothPhysicsState rhs = proxyStates[FMath::Max(i - 1, 0)];
                    // The best playback state (closest to 100 ms old (default time))
                    FSmoothPhysicsState lhs = proxyStates[i];

                    // Use the time between the two slots to determine if interpolation is necessary
                    int64 length = (int64)(rhs.timestamp - lhs.timestamp);
                    double t = 0.0F;
                    // As the time difference gets closer to 100 ms t gets closer to 1 in
                    // which case rhs is only used
                    if (length > 1)
                        t = (double)(interpolationTime - lhs.timestamp) / (double)length;

                    // if t=0 => lhs is used directly
                    FVector pos = FMath::Lerp(lhs.pos, rhs.pos, t);
                    FRotator rot = FMath::Lerp(lhs.rot, rhs.rot, t);
                    SetActorLocationAndRotation(pos, rot);
                    return;
                }
            }
        }
        // Use extrapolation
        else
        {
            FSmoothPhysicsState latest = proxyStates[0];

            uint64 extrapolationLength = interpolationTime - latest.timestamp;
            // Don't extrapolate for more than [extrapolationLimit] milliseconds
            if (extrapolationLength < extrapolationLimit)
            {
                FVector pos = latest.pos + latest.vel * ((float)extrapolationLength * 0.001f);
                FRotator rot = latest.rot;
                SetActorLocationAndRotation(pos, rot);
            }
            else
            {
                // Don't move. If we're this far away from the server, we must be pretty laggy.
                // Wait to catch up with the server.
            }
        }
    }
}