Collision with movement along Spline

Hello!

I’m currently trying to develop a game prototype using Blueprints. The game is a 2.5D Sidescroller where I’ve set the character up to move along a fixed path using a Spline. So far, movement has been working quite well, up until I starting setting up obstacles (plain boxes) with collision.

The setup I have is very similar to what you find in [this thread][1].

The issue I’m having is that as the character runs into an object, the variable that keeps track of the total distance traveled across the spline (‘Spline Distance’) keeps increasing. So while the character haven’t appeared to move (it’s simply been running into the obstacble), it’s location along the Spline has changed. If the character then were to jump up above the obstacle, once more enabling them to move forward, they’d “teleport” to the correct distance along spline.

I’ve tried solving this several ways; moving the character back 1 cm everytime they collide with an obstacle, setting ‘Spline Distance’ to itself to place the character at a point where it didn’t collide with the obstacle, not doing anything if collision is detected, and some other things. Nothing have worked.
Either the character gets stuck “inside” the obstacle, or I get a weird case where the character tries to force itself to the new location by sliding along the side of the obstacle until it reaches around the corner and teleports to the “correct” location, and sometimes I get both depending on direction.

Here’s a snapshots of the Blueprints handling character movement:

Thanks in advance.

Alright, came up with a functioning solution myself.

I declare an additional float variable called “NewSplineDistance”. Somewhere at the start of the blueprint I set NewSplineDistance to be SplineDistance + Velocity (basically). NewSplineDistance is then used calculate the new location of the actor along the spline, which is checked for collision by enabling Sweep (see SetWorldLocationAndRotation). If movement was successful, set SplineDistance to NewSplineDistance. If the character collided, and movement failed, reset the character’s location using SplineDistance.

Heyho,

I’m stuck with pretty much the same problem. I’m glad that you posted how you solved it, that should get me on the right track. Do you think you could post the blueprint of the final setup? That would be amazing!

Thanks a lot! :slight_smile:

This problem and solution sounds exactly what I need. Can you or anyone else go into detail about how you set NewSplineDistance. Maybe show a blueprint? I have been stuck on this for 2 days now.

I’ll happily show you what the final blueprint looks like :slight_smile:
Now, it’s been a couple of months since I looked at this project, so I might have forgotten some specifics.

And I’m gonna try and walk you through this, for the sake of clarity (I hope):

The blueprint repeats every frame that InputAxis MoveForward is triggered. It starts off by checking if there’s any new movement to calculate, otherwise it ends up resetting the characters rotation eveytime it stops moving.

If there is any new rotation to calculate, the blueprint goes ahead and calculates the intended new position along the Spline (MovementAlongSpline; see the green panel in the image in the original post), and make a Float variable called NewSplineDistance hold that value for the time being. This temporary value is calculated off of the characters current position along the Spline, which is stored in another Float called SplineDistance.

NewSplineDistance is then used to calculate the characters new rotation, forward direction, and location (Calculate Rotation; see the red panel in the image in the original post). Then the blueprint takes all these new values and happily tries to apply them to the character.

In SetActorLocationAndRotation it’s important to check the box marked Sweep. This is used to determine if the character has walked into an obstacle that it can’t pass through or not. We determine this by breaking up Sweep Hit Result, and running the Blocking Hit boolean value through a Branch. And this is where the magic happends.

If the character ran into an obstacle, then it reverts the movement by setting the characters position to it’s original value (SplineDistance).

If the character didn’t run into an obstacle, then it takes the new position along the spline (NewSplineDistance) and make that the value of the original position (Spline Distance), as well as keeping all the changes made to the character.

see post below :slight_smile:

That depends on what you mean by “flying” and “glitchy”. Videos, images, and/or detailed descriptions are very helpful, as being specific is key to anything programming :wink:

Thanks for taking the time for this. It did help me out but I find that if I run into a wall it still has this juddering effect that I cannot get rid of. It also can get stuck when stepping off a ledge.

This solution work only if you want to stop everytime hit an obstacle, but if you hit a stair that you want climb it? I’ll explain … for example, imagine you are moving your character along spline and encounter a stair mesh that you want to climb on the stair side and block if you are on the “wall side”. I make a draw to explain the problem better:

136769-problem.png

i don’t think your solution work. Do you have any idea for solve this problem?

@hidrogen, I have solved the problem with stairs and ramps, as that has been an issue for me as well.

My solution is do everything in the solution so far, but instead of using the built-in Sweep checkbox, you’ll have to go to some trouble of doing a Capsule Trace yourself. This gives you the ability to make the stopping of the character conditional on things like whether the Impact point’s World Location is higher than the bottom of the Capsule plus the Step Up Height.

The Capsule Trace only needs to be a small distance from the character, in the direction of travel. You might trace to a distance equal to the input velocity or something like that.

If the impact point is higher than the character’s step up height, then you kill all the XY velocity of the Actor AND the character movement component, AND zero the additive variable that would have progressed the distance along spline.

My solution results in jitters near the blocking wall, but works perfectly in enabling both blocking walls and stair climbing. It takes a dozen nodes or more to set up though.

I am now working on how to eliminate the jitters, which I think are occurring because when I reset the DistanceAlongSpline (or whatever you call it in your blueprint – the variable that is input to set the actor location on the spline), I am setting it back just a touch too far, maybe. I don’t know.

Maybe I’ll check the trace distance and if it comes up too short, I’ll just prevent all movement in the trace direction or something like that.