Between the Folds #003 - Splinecarts


We decided to create a sort of “minecart” system for WHALIEN in order to lighten up the gameplay. Moreover, this system should serve as a fun and interactive means of transportation, and allow the player to push and pull the minecarts with their magnetic forces.

(A splinecart being pushed downhill)



Rails:

For the rails, we once again resorted to our trusty friends - Splines and SplineMeshes. The Splines define the shape of the rails and for each segment of the spline, the rail is represented by a SplineMesh.

Since we create and calculate our SplineMeshes in the Blueprint Construction Script, the rail mesh instantly adapts to changes in the underlying spline, simplifying the placement of the rails significantly.

(The rail can be created and adjusted easily in the editor)

The Blueprint implementation of SplineMeshComponents provides all elements we need to update the mesh in real time in the editor. The magic Blueprint-node for this is SetStartAndEnd, which takes the location and tangent at the start and end of the underlying spline segment and warps the mesh to overlap exactly with the spline.

(Spline-)carts:

Movement on the rails is handled by our SplinecartComponent (named for obvious reasons). This component can be attached to any actor, allowing it to move along the rail and turning the actor into a “Splinecart”.

Essentially any object can be turned into a Splinecart using the SplinecartComponent - even objects that the player cannot influence because they may be too heavy. For this, we added the option for the Splinecart to move automatically with a given speed.

(A ducky moving along the rail by themselves)

By default, the Splinecart’s physics simulation and Tick-function is disabled. We only enable them whenever the Splinecart is supposed to move along the rail in order to conserve processing power. When that’s the case, we constrain the minecart to the rail by overwriting its location and velocity each frame. Each frame, we calculate the minecart’s closest location on the rail using the functions FindInputKeyClosestToWorldLocation() and GetTransformAtSplineInputKey(). We calculate the new velocity by multiplying the current velocity (GetPhysicsLinearVelocity) with the direction along the spline (GetDirectionAtSplineInputKey).

(Code to calculate the position and velocity of our splinecart)

Difficulties:

Initially we had difficulties retaining the player on the minecart while it was moving. This was especially noticeable at downhill passages and in sharp corners. We fixed these issues by applying two small changes:

The bug while moving downhill originated from the minecart’s position being updated after the character. That meant that we would sometimes offset the minecart into the character, causing the character to slide around on the Splinecart. We fixed this issue by setting the SplineCartComponent’s TickGroup to ETickingGroup::TG_PrePhysics to guarantee that the splinecart is always updated before the character has its gravity applied.

In sharp corners the minecart was rotated very abruptly, which on the one hand looked very strange and on the other hand would sometimes throw the character off the minecart. 

causing the character to fall off frequently. We fixed this problem by interpolating between the minecart’s current and its desired rotation, based on the current position along the spline. Interpolating the rotation is particularly easy in UE4 using the function FMath::QInterpTo().

(Splinecart going around a steep corner. Left: Without the fixes; Right: with the proposed fixes)

If you would like to know anything else about our splinecarts, ask away!

- Andi, Ralf

Leave a comment

Log in with itch.io to leave a comment.