Character Movement Not Consistent Along Spline (Blueprint)

I’m attempting to create a movement system similar to Aaero or Iridion 3D. (Player is autoscrolling forward in a 3D environment, with the camera behind them. The key thing is that the camera stays in the “center” of the space.) The goal is to keep the player loosely “locked” to a spline that will not be a straight line in the level. (Spline system I have implemented does everything in the construction script and won’t be changed at runtime. It’s heavily based on the following live training video: Using Splines & Spline Components | Live Training | Unreal Engine - YouTube)

The issue I am having is that the player seems to slow down quite a bit when nearing a spline point, more notably when there’s a larger distance between said points. I’d like the movement to stay consistent, so that there’s not this sudden jitter that happens that causes the player to visually move further forward or backwards in space from the camera. (Sometimes fairly rapidly)

Here’s the scripts that control the movement system for the player:

Here’s the script for the camera movement, which is a separate actor:

Would like to see a video showing your issue.

As for your actor: How is your hierarchy organized? I see you are moving the actor and camera along the spline?

Judging from your reference, I would approach it like this: Move actor along spline, move ship component with input within a magnitud in local translation on the ZY plane. For example:

Camera as component of the actor moves with it (not along the spline), but not a child of the ship with a “soft” look at. This way you’ll only need one tick event and 1 actor along the spline (each level can be 1 spline entirely from start to finish). Everything handled within one blueprint.

Like so:

This is packed and ready to move along a single spline.

Like Aaero:

Video shows my player component hierarchy and what happens when moving along the spline.

Edit: Removed unnecessary attachment and disclaimer. Grammar fix.

  1. shouldn’t the camera actually just be fixed to the track?
    You did mention this. But then it looks as if the camera is not fixed since it jets out of the wall

  2. the spline points / their distance, placement etc. Don’t matter.

  3. the fact the camera seems to change near a ring, is that intended or a visual effect due to the fact the ring is way bigger and the ship actually slows?

  4. outputting your ship speed to screen would help you debug a lot.

Other than this,
Could be a billion issues.

  1. make sure the delta time is multiplied into the movement.

  2. movement along spline has a few different options and ways to do it.

In some, you could be limited by the fact that you are using a 0 to 1 float to move along the spline (an alpha value).
On very, very long splines you would then obviously loose precision based on how many decimal points it can safely handle.
(Using C++ you could just use a double and not have issues I suppose).

If that’s the issue, the other way is to get the actual spline point and use use node that requires the point index.
(Keeping track of the index manually as you progress would be better than calculating it all the time).

  1. I have a cube moving with variable speed along a track while causing physics simulations to do things. I’ll share the screenshot of the movement when I access it tomorrow if you are still looking.
    Doesn’t jitter, the track is 3km long…

Jitter is probably because the tick rate of the actor setting the ship on the spline is slower than the viewports fps. If you set tick rate and t.MaxFPS to the same, jitter should be gone. Like in the video below: actor tick rate = 1/60 and t.MaxFPS 60.

Try not using this and disable all Interp nodes. Set the actor location and rotation linearly along spline → Distance++ per frame. See what happens.

This is all you need to move an actor along a spline:

A little side note: spline distances goes from 0-1. That 1000 is just me being lazy for the sake of demo. :innocent:

That’s actually the way you get issues. with the value being 0 to 1.
This BP is a total mess, as I only ever prototyped it, so I’ll give you pseudo-code.

Assumption: Travel speed is handled by a variable who’s value is in KPH, thus you multiply * 3.6 to get 1mps. Multiply times Delta Seconds to get frame speed.
ADD to a Position variable.
Set the new Position variable for this frame (if done on tick).
A: Check if the position if < spline length. IF it is not, reverse the process or reset the process - maybe win a game in your case?
B: (true) apply the position:
Position Variable plugged into distance for Get Location At Distance Along Spline.

In my case, I line trace 4 times, one at each corner of the platform like a car, do the math, and orient the platform to conform to the terrain. This means I derive my Z from the trace.
And I also adjust the Get Rotation at Distance along spline node result, based on how the platform has to conform to the terrain.

In your case I think these last 2 steps are basically pointless.

The final part is you just SetActorLocationAndRotation with the results you got.

The alternative for capsule collisions would be to add movement input.
HOWEVER - this method won’t necessarily work because the Position you are adding to every frame is then governed/limited by the movement component. You have to work around that or read the speed from the movement component to use. You also assume that you aren’t.

This becomes Get LastUpdateVelocity → VectorLenght as the speed variable (no x 3.6).
And you substitute the get world location on spline node for GetDirectionatDistanceAlongSpline

Move forward from that…

1 Like

I’ve implemented the new setup you suggested, now I’m just having a problem keeping the camera behind the player.

  1. Yes, the camera was locked onto the spline directly for the video. It’s just the spline went outside the bounds of the tunnel due to the Bezier curves. (As shown below.) It’s an issue I may have to solve later. However, it doesn’t usually pop up without doing some extreme movement of nearby spline points.

  1. The camera changing like that is unwanted.

  2. The speed was handled by a float value being set at begin play and multiplied by delta seconds per tick. It hovered around 60 with little fluctuation for the tests I did.

  3. I was using a setup that fetched the player location and determined the distance along the spline on tick, and then stored that to a variable. (The first Blueprint Pastebin)

  4. I am sadly not versed in C++ enough to even begin coding a project.

I forgot to attach this to when I was posting my Blueprints. It was what allowed me to get the distance along spline.

  1. The speed was actually a variable set at the beginning of the level. (Set by the BPM of the song.) Then multiplied by delta seconds to keep it frame-rate independent.

  2. I actually think the line tracing bit would come in handy, since there’s oftentimes a weird transition between corners and straightaways with the spline. Visually, the player is on a straightaway but suddenly veers a bit to the left or right before straightening back out. (The Bezier curves don’t like to play nice. Probably something I’m doing wrong.) Not sure how I’d go about it though given that everything is so reliant on the spline at this time.

There’s several ways.

From what I understand the ship is flying within a tube.

To get an accurate reading of where you are within a tube you need a minimum of 4 traces, each 90deg away from another.

The distances will then tell you your position within the cylinder.

This can allow you to adjust things or throw in special effects when the distance is below a certain threshold (either by the player causing it, or the spline following going off a tangent).

Within the cylinder I don’t think Rotation (of the ship) matters one bit. It could even be upside down…
The Yaw is probably the only rotational value you may need to consider as “automated”.

You can actually derive that from any of the traces… which would lead possibly to a more correct placement - it depends on what the trace traces.

The trig on that is acrually simple. You can cross the trace normal with the ship right vector to get the corrected forward vector.
That shuld place the ship on a forward heading oriented in respect to the side of the tunnel you traced.

The other possible reason it isn’t working is as you said, you may be doing stuff wrong.

For the most part, I can’t look at your BPs over mobile. Would be best if you shared scren-shots on the forum directly.

Re distance along spline.
Isn’t it just better for your pospose to do as I said and sum it up from the start? Particularly if it also needs to drive the beat of the song or vice-versa?

Getting your current position won’t really help IMHO it’s reactive vs active. You would be better off with the active approach.

  1. Currently, these are the only Blueprints controlling the player and camera movement. (The Blueprint setup suggested by pezzott1 earlier in this thread)

  1. Currently, the camera is moving faster than the player and will quickly leave the player behind. (Unwanted)

  2. Yes, the ship is flying in a tube/tunnel. It’s made up of spline meshes that construct around the spline.

  3. I don’t really mind what technique allows the player to move, as long as it stays within the bounds of the tunnel, autoscrolls, and maintains its offset to the walls while taking corners.

  4. If it helps any, the music drives the player. I actually want the player to pass rings in time to the bpm of the song. I don’t know if there’s a way to set points to be an exact distance from the last point. As such, I was just going to use the spline point distances and alter the ship speed accordingly.

Edit: Grammar fix.

Look. There’s probably a billion ways to do this right.

But since you are always moving forward, why not use the correct components?
Ei: make a character BP with a movement component, set it to flying, constantly add inpulse.

On Tick you ray trace to 4 cardinal directions and manually detect where you are within the cylinder.

Based on the values of the hits you adjust/correct the heading.

That way it won’t matter how far along the spline you are, or what the spline does, you’ll always just edge forward while staying inside of the tunnel.

For the type of game you want, this is likely a lot better compared to following a spline, since you can let the player feel like he’s more in control…

The only thing that is potentially problematic when working with the line traces is to automatically turn into a joined tunnel - mostly because there’s no guarantee the line trace will be at a precise position when it first starts to detect that a hit is missing.
If the tunnel is 3 or 4 times the ship, the automated turn will also just work fine.

It depends on how much time you want to put into the main gameplay system being good.

Ad far as synching with music / making sure you are on beat, I would just have the automated generation use the music information to generate so its always on time at the music’s speed of choice.

This is why diverging from spline following would be better here. You could have a ton of intersections or very few depending on what instrument or beat is in use.
You could potentially also generate the next song on the run or swap out track from settings and spawn in the new beat track seamlessly- without having to worry at all about “where” on the spline you are.
The song itself would become your way to determine progress…

Yea… it has some issues:

  1. Diagonal movement was double the speed.
  2. Had to redo parts to get closest point of border.
  3. Was frame rate dependant.
  4. Could not modify radius and set bounds automatically.
  5. Useless with other than keyboard.

So I redid the math… now it’s a bit more versalite.

  1. It now works ok(ish) with a controller.
  2. Radius of bounds updates everything and can changed during gameplay.
  3. Can get distance and position of closest point in bounds.
  4. This same math can be modifiied to have the actor/pawn move along the tunnel with impulse rather than in local as it is now… you could have the actor’s forward vector in paralel with the spline without the actor actually being attached to it but it’s a lot of math and I already had my fun.

Anyways, it’s just another option.

Also thank you @MostHost_LA for your feedback (even if it wasn’t for me). Learned a lot and gave me new ideas on how something like this could work. Just hope i was of some help.

The new mess:

Function to limit ship to radius:

Thank you both for pointing me in the right direction. I think I’ll try to move forward with a hybrid of your suggestions. (Camera/Player movement range limited by radius and keeping camera and ship in one actor / using Add Movement Input and line tracing for forward movement and actor rotation.)

1 Like