I actually worked really hard on this as well, and did in fact solve it!
The trick is to do some math at the point of player overlap with the spline mesh. First you get the world position of all spline points, then compare the actor location to all of them to find the two NEAREST points. Then you do a weighted average based on the player distance from each point (i.e. he’s closest to points 3 and 4, and is 70% of the way from 3 to 4).
THEN, you calculate the Distance Along Spline at each of the two closest points, and apply the same weighted average to them (so find the world distance 70% of the way between 3 and 4), and store it as a variable.
Then every tick, you Set the actor location to the World Location At that Distance Along Spline, then add a fixed amount (the grind “velocity”) to that value (scaled by Delta Time for smoothness), offset by whatever value you need for the grind to look right (so the capsule doesn’t sink into the rail or whatever).
Also, when performing the initial check, you use the actor forward vector (or control rot forward vector, depending on how your game plays, I use the actor vector) scaled up by a few units and REperform the “which is closer” check against his current location; this lets you determine whether the character is FACING the lower or higher point on the spline; you can use this to set a Bool which indicates whether you’re traveling along the spline forward or backward, and in turn indicates whether your “velocity” float applied to distance every tick should be positive or negative.
The last bit is to have your tick thread here hit a branch which checks whether or not you’ve reached the ends of the rail (I use checks on the distance at the final spline point, and/or 0; I think these days there’s a node to check for percentage-along-spline-at-a-point, but I did my subsystem before that), and then stop the ticking and use a Launch node to “shoot” them off the rail using world direction at spline point, and scaling that value (by trial and error) to be consistent with your rail traveling speed.
Don’t forget to disable gravity while using this set location tick path; UE attempts to recompute Z position every tick due to gravity and your setting of the player location will undo that every tick, meaning that you will sink further into the rail while grinding if your framerate dips (since you’ll be canceling the effect of gravity more frequently at higher FPS, meaning UE will recalculate your distance to be less low each tick than when in low FPS.)
The last bit for me was to implement some IK to track the feet to the rail at a Distance Along Spline some given distance away from the player’s location, so that around curves or up slopes the player’s grinding pose tracks the rail accurately. I’ve currently tried implementing a rolling/looping solution (by specifying rotations for an array at each spline point and getting the actor to track them, so he can grind loop-de-loops and such) but not made much progress, mostly because UE doesn’t allow you to properly specify fully 3D spline rolls and you get weird tracking bugs at the point where the spline loops over.
It’s late tonight but tomorrow I’ll try to get some screenshots and video of my system so you can copy it!