Tutorial: Blueprint Spline locked sidescroller (e.g. Klonoa / Pandemonium style game)

I’m very new to blueprints so please feel free to share if you know a better way to achieve the same result and please do post videos of anything you make with this method. Would be great to see what people come up with.

This example uses Blueprint sidescroller project as a start point and will modify it to the point your character is locked to a spline so that all you are pressing is left and right on the left analogue stick as you can see in the video below (whilst it might look quite crude, the idea is a start point for people to develop from)

  • Create a new Actor Blueprint (in this example named Spline)

  • In the Components view of this BP, create a spline (shape, not spline mesh).

  • Open the MyCharacter blueprint and go to the Graph view.

  • Create a Variable in the left panel and call it Spline_blueprint or an appropriate name.

  • Open the Variable Type dropdown list below and type _C into the search box. This will list all of your blueprints that you can reference. Select Spline_C from the Object section.

  • Click the eye icon next to your new variable and it will turn yellow.

  • Finally you MUST write something in the Tooltip entry box in order to choose what blueprint will be referenced when you reach the next steps. e.g. ‘Referenced BP’.

  • You will see the eye icon has turned green if you have done this correctly.

  • Delete Player Start in level and drag an instance of the Mycharacter BP into level.
  • In Details panel set Auto Possess to Player 0 (this is now your player start)
  • Also drag an instance of your Spline blueprint into the level and place some spline points (click on end point and Alt + Left click drag new points out)
  • Return to the MyCharacter blueprint you placed and look in the details panel for ‘Spline Blueprint’. This is the exposed variable you previously made. Click on the dropdown box and choose your Spline blueprint from the list.


In character BP graph create the following setup:


This says that when Play Begins, the variable ‘Distance Along Spline’ is set to 0. After this the Capsule Component (i.e. the character Root) is moved to whatever location is set within that variable (you will need to promote Distance entry in the “Get World Location at Distance Along Spline” node to a variable named ‘Distance Along Spline’) and that the spline being referenced is Spline 1 in the blueprint called Spline.

SAVE YOUR BLUEPRINTS!

You can see this working if the start point of your spline in the level is set away from the position of the MyCharacter blueprint.

Dropping into game, you will see that the character spawns at the start of the spline, rather than the location of the MyCharacter blueprint in the level.


Now that we have set our first location, we want to set a new location each frame. This location will be defined by the ‘Distance Along Spline’ variable we currently have. Up to now it has just been set to 0, but you can change this value however you like.
In my example I will use the ‘InputAxis MoveRight’ event which is already setup in the project to modify the variable based on how much I push the left stick on a 360 controller.

As the variable will be changing, we want to update the location every frame.

Create the following additions to the MyCharacter Graph:


In this setup, whenever a MoveRight event fires (by pushing the left stick or using the assigned keyboard shortcuts) the axis value (which can be positive or negative) is added to the current value stored in the ‘Distance Along Spline’ variable. The resulting value is stored in the variable and a new location is set per Tick (even if this location hasn’t changed).


Whilst you can move back and forth along the spline, you will notice that your height doesn’t change as the world location is being set in all 3 axes (X,Y and Z). The movement is also incredibly slow and doesn’t match the leg movement of the character so you might want to add in a multiply node (Float*Float) before the ‘Add’ node to increase the Axis Value.


At this point I’m learning as I write this so I might not have the most graceful solution. I’ve never used a Trace but it seems like the right thing to do… so… fingers crossed! :slight_smile:

If we promote the return value of the ‘Get World Location at Distance Along Spline’ to a new variable called ‘Current Location’, we can store this location every Tick and fire a Trace from this location at the same time.


This example will fire the trace from the current location to the same location in X and Y, down to a world height of 0
With the Draw Debug Type set to Persistent, we can drop into game and see that the line trace is indeed firing down from the player and hitting anything at 0 height in Z and above (you might need to add more types into the Make Array node based on your level contents or change the Z height to a negative value).


If we now break the Out Hit of the Line Trace to a Hit Result, we can create a new variable from the Impact Point and called ‘Trace Hit Location’ and set THIS as the new World Location of the Capsule.


If you hit Play at this point you will see that the player sits on the ground, but his waist is intersecting the ground. If you add in a Vector+Vector node you can offset the Trace Hit Location (I’ve used 100 to lift the character 1m upwards of the Trace Impact Point). Further to this I have also added the new variable ‘Jump Height’ into the equation. When InputAction Jump is pressed, an offset of 200 units (2m) will occur in Z. When it is released, this value will be 0 in Z.


Play now and you will see the snap to jump height whilst you hold the jump button, otherwise you should be at ground height.


This started out as a brief tutorial for a forum member who was struggling with spline locking a player/camera but has turned into something bigger so rather than refining the jump I will simply add the correct character rotation and leave it here…

There are a few steps:

  • Go to the InputAxis MoveRight event and promote the Axis Value to a new variable


Now we can set World Rotation of the Capsule Component at the current Distance Along the Spline, just as we initially set the World Location.


If you hit play you will see that the rotation is only correct whilst running from left to right, but he runs backwards (moonwalks) when going the other direction along the spline. This is the reason we made the Axis Value variable in the previous steps.

With the following setup I have stored the Current Rotation as a variable and then added a Branch to the exec. If the MoveRight Axis Value is equal to, or greater than 0, then the stored current rotation will be set on the Capsule. If not (i.e. the Axis Value is negative) then 180 degrees in Z will be added to the Current rotation and applied to the capsule, resulting in him facing the correct way whilst running backwards along the spline.


Update your camera position and rotation from the same spline or even its own spline (or lock it to the player) and you’ll get a nice drift through the world which you’ll see when I get around to updating my own thread here - Seeking guidance for movement system (spline locked, side on, free "flight") - Blueprint - Epic Developer Community Forums

There’s lots to refine here such as the jump, the fact you snap up surfaces when you meet them, and plenty more, but I hope it’s helpful to people. It’s been good to learn new things as I wrote this up and I’ll be showing off my own implementation soon, but for now it’s bedtime.

Enjoy folks!

As mentioned above. From my thread that started this whole endeavour, my latest project progress:
https://youtube.com/watch?v=YAz9NV0vABE

Thread: Seeking guidance for movement system (spline locked, side on, free "flight") - Blueprint - Epic Developer Community Forums

Reserved for any future updates

Haven’t gone thru the whole thing yet, but it looks super awesome. Thanks dude!

No problem. Let me know if you use any of the ideas shown here in your own work :slight_smile:

Hi Monophobe!

You can make the character hit the ground just with default gravity. You only need to break the result of “Get World Location at Distance Along Spline” into three floats, then you get only “X” and “Y” to create a new Vector. But you will still need the “Z” and you will get it from the “Get World Location” from the “Capsule Component”. Use this new Vector to feed the “Set World Location” or “Set Actor Location” (this don’t need to get the “Capsule Component”). Take a look:

You will need to break your rotation as well, and use only the “Yaw” component:

You can use the default function for jumping, like this:

ec0a34f564ac71caabe6bbab17620c258d8f098d.jpeg

To control the character speed, you will need to get “Delta Seconds”, multiply by “Max Speed” and “Axis Value”:

This is the whole thing I did:

Cheers!

Thanks, Felle we could make some “Nights into Dreams” remake.

This is great! Fantastic work!

Sorry for reviving, but does anyone know how to keep the velocity of the jump while not pressing the button?

I found a fix, here’s a wall of text explaining it:


We are going to need to set a track for our character, move the blueprint from the content browser and then simply make the path selecting the second node and pressing alt while moving it, this will create a second point.


Rotation and scale both affect the way curves are made, this are esentially dumbed down beizer curves, play with them and make sure you get a smooth curve.


Now, we need to make this actually work, go to your character blueprint and add a variable of the class of your spline blueprint and make it editable.


If you have a pawn spawn point get rid of it, simply add your character from the content editor and select your spline blueprint from the selector.


You are now going to need a float variable named spline distance, you can make editable if you want, also create a starting spline distance one if you want to.Add a function and make it run on begin play


What this function does is calculate the position the player would be if he was “x” into the spline (x=starting spline distance) and moves him there, I recommend to set the starting spline distance to something like 10, and block the start of the spline with a brush or something, because if the player reaches the start he might get stuck, this is not much of a problem tho, you can simply add a invisible wall.You now are going to need to add a boolean variable named facing, this is esentially a boolean that tells us where the character is facing, if he’s facing right make it false, if left make it true. (You can make this values what you want tho)Now, add this function to even tick


What this essnetially does is, gets the horizontal velocity of the player (we aren’t using the Z because the spline movement is supposed to be horizontal) we then get the vector length wich gives us the speed in unreal’s standard speed unit (I don’t what the name of this is) then multiplies it per the delta time (seconds since last frame, this allows the game to run at the same speed, even if the hardware ***** up and goes slow for a second), and then adds it to the spline distance (because it’s the same unit), or substracts it if the character is facing left.If you are a good observer you will have noticed there is more to the right, let’s take a look at it.


What we are doing here is get the world location based on the spline distance and get the Z from the current actor location, this is because jumping is independent of the spline, so we don’t need to set it, we then set the actor locatin and use the sweep option of set actor location, this is because sweep does a collision check before moving, and also it doesn’t matter if it failed, because we are calculating the distance from the velocity, so we are safe from breaking it, we also get the rotation alogn the spline and set it… and that’s all, you can get the sources for both functions here:

Init

Update

Thanks for this EIREXE, incredibly useful.

This is the first time I’ve known about using the Sweep option. I’m using some of what you have here and combining it with my own setup to finally get collisions working in my game! :smiley:

Blending jump smoothly

I’ve followed your example and it worked perfectly. I do have one question regarding the jump. I have a similar setup with the jump (though I’m not using it as a jump, but to move in different axis along the spline, but the setup is similar to what you have illustrated). How would you suggest I get this to smoothly transition from one position to another? currently it just snaps to the new location and I’d like it to drift smoothly into position.

Thanks!

Many thanks Monophobe :slight_smile:

Hi, for my game I want wind that goes in all sorts of directions so I need to be able to add a force to the character in the direction of the spline, do you know if this is possible bearing in mind that my character is not always locked to the spline?

Hi Monophobe , First i want to thank you for figuring this out. Is it possible for you to post a sample project demoing this? I am unable to get this to work and it would be very helpful if I can pick apart a sample project. Thanks for posting the tutorial!

Hi, thanx for the tutorial! :slight_smile:
It works here but as soon as I delete the character BP from the level and drop it back in, I get “acces none” errors:

“Error Accessed None ‘SplineBlueprint’ from node Construction Script in blueprint ThirdPersonCharacter
Error Accessed None from node Construction Script in blueprint ThirdPersonCharacter”

But the Spline BP is selected in the character BP. Any idea what causes this?

Greets,

Hallo,
I cant find the variable type Spline_C in the dropdown was it renamed?

This probably means that one or more of your execute nodes is messed up, try relinking them.

Started using this tutorial, so far so good, but I have a problem near the beginning. The first section of using Blueprints, you start with ‘Event begin play’ and from that you have ‘Set distance along spline’. I can’t find the ‘Set distance along spline’ node and I’m unsure what I’m doing wrong, I’m in the MyCharacter blueprint graph, which as far as I know is where I should be. Any help appreciated, thanks!

Hi, i had the same problem, i think it’s just a float variable you create, it looks the same anyway, however i got stuck just after that, i cant change the “get world location” node to have the spline as the target, i just get spline component reference is not compatible with cube blueprint reference.

(i’m not quite trying to do the same thing, i need an object to follow the spline not the player, so i’m making the blueprint on a cube to test)

I did something similar to you but found the walking looking ackward. Basically the movement input increases “DistanceAlongSpline” float just as you did but the amount is set to be "character max movement speed * delta seconds). This is then used to calculate the distance between actor and world location along spline and then plugged into a “add movement input” node. This ensures that the character naturally moves along the spline with his max walking speed. Then you need to adjust the control rotation so that the camera works but it overall produces a very nice and clean walking along spline system.

Cheers,

Max