Created
May 30, 2018 17:25
-
-
Save braustin20/220145d54aa1f419e719cf607a637765 to your computer and use it in GitHub Desktop.
Unreal 4 spline movement script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void ASplineCharacter::MoveRight(float Value) | |
{ | |
if (GameStateRef == nullptr || GameStateRef->MovementSpline == nullptr) | |
{ | |
AddMovementInput(FVector(0.f, -1.f, 0.f), Value); | |
return; | |
} | |
//Orient and move player in the direction of the spline | |
SplineDirection = GameStateRef->MovementSpline->Spline->FindDirectionClosestToWorldLocation(GetActorLocation(), ESplineCoordinateSpace::World); | |
SplineDirection.Z = 0.0f; | |
SplineDirection.Normalize(); | |
AddMovementInput(SplineDirection, Value); | |
SplineStatus = GameStateRef->MovementSpline->ReachedSplineLimit(GetActorLocation() + GetCharacterMovement()->GetPendingInputVector() * 50.0f); | |
//If we're at the end of the spline and are clamping movement, stop the player. Otherwise, adjust lateral movement. | |
if (ClampToSpline && SplineStatus != ESplineLocationStatus::SL_OnSpline) | |
{ | |
//NOTE: Could use a ternary for this but decided a switch was more readable | |
switch (SplineStatus) { | |
case ESplineLocationStatus::SL_ReachedBegin : | |
SplineLocation = GameStateRef->MovementSpline->Spline->GetLocationAtDistanceAlongSpline(GameStateRef->MovementSpline->DistanceAtStart, ESplineCoordinateSpace::World); | |
break; | |
case ESplineLocationStatus::SL_ReachedEnd : | |
SplineLocation = GameStateRef->MovementSpline->Spline->GetLocationAtDistanceAlongSpline(GameStateRef->MovementSpline->DistanceAtEnd, ESplineCoordinateSpace::World); | |
break; | |
} | |
GetMovementComponent()->ConsumeInputVector(); | |
SplineLocation.Z = GetActorLocation().Z; | |
} | |
else | |
{ | |
//Find the nearest point to player on the spline | |
SplineLocation = GameStateRef->MovementSpline->Spline->FindLocationClosestToWorldLocation(GetActorLocation(), ESplineCoordinateSpace::World); | |
if (CameraActorRef != nullptr) | |
CameraActorRef->TargetLocation = FVector(GetActorLocation().X, GetActorLocation().Y, SplineLocation.Z); | |
SplineLocation.Z = GetActorLocation().Z; | |
//Get the vector from the player's location to the nearest point on the spline | |
FVector SplineLocationVector = (GetActorLocation() - SplineLocation); | |
SplineLocationVector.Z = GetActorLocation().Z; | |
//Calculate the tangent of the spline at the nearest point and determine the distance to the player | |
FVector splineTangent = FVector::CrossProduct(SplineDirection, FVector::UpVector); | |
DistanceToSpline = FVector::DotProduct(SplineLocationVector, splineTangent); | |
//Find the spline point directly to the side of the player | |
//This is necessary to prevent forward/backward movement along the spline unless applied by the CharacterMovement component | |
SplineLocation = -DistanceToSpline * splineTangent.GetSafeNormal() + GetActorLocation(); | |
} | |
//Smoothly move the player onto the spline | |
SplineLocation = FMath::VInterpTo(GetActorLocation(), SplineLocation, GetWorld()->GetDeltaSeconds(), SplineLerpSpeed); | |
SetActorLocation(SplineLocation, true, nullptr,ETeleportType::TeleportPhysics); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment