For some weird reasons, the built-in move_and_slide doesn't add the platform velocity to an object when it slides from 1 platform to another. The result can be seen on the lower object which does not slide up the slope despite being run towards the latter on a platform moving at (300, 0) per second.
To counteract this, I simply do not consider platform velocity as a separate component of the returned motion vector in my move_and_slide substitute, which use move_and_collide repeatedly to achieve a sliding effect.
This, of course, has some troubles on its own (not shown in the video, sorry). For 1, move_and_collide often makes for very janky movements on vertically moving platforms, like you character seemingly to barely jump when you make them do so on an upward moving platform, or stopping and hovering mid-air for a while before falling back down when they land on a downward moving platform.
The occurences above will happen when you merely slide the motion vector along the normal of a moving platform. Why? say a platform with a normal facing your character of (0, -1) is moving downward at (0, 100), and you character lands on it at (0, 110). Calling slide with your character's motion will return (0, 0), completely without considering the platform's motion. Hence, to make the player inherit the platform's motion, I just add the platform's motion in the direction of the normal to the returned motion vector (and to prevent some OTHER problems that I will not explain yet, I do not do so to the actual vector being used to move the object, which is just motion * delta and no more modifications).
But wait, adding the platform's velocity? What if my player moving up at (0, -70) collides with a normal of (0, 1) of a platform moving up at (0, -100)? Wouldn't that give the player an illogical boost in upward velocity? Well, logically speaking, that should be an impossible occurence and if it did happen, that means I might have messed up somewhere down the line. Ah but what the heck? I also made a failsafe. The added velocity after sliding is actually the largest motion in the direction of the normal (dot product with the normal * the normal), so that if the player is moving slower than the platform in the direction into the colliding surface, it wouldn't get the platform's motion in that direction (and if the player is moving faster in that direction, it would be slowed down to match the platform's motion). (For those confused about why I pick the maximum, it's because the normal is the direction towards the player perpendicular to the surface, so the higher a motion's component in the normal is, the slower that motion is running against the surface)
So, formula?
var temp = motion;
motion = motion.slide(collision.normal);
motion += collision.normal * max(temp.dot(normal), collision.collider_velocity.dot(normal));
Which can be written as:
motion = motion - collision.normal * collision.normal.dot(motion) + collision.normal * max(temp.dot(normal), collision.collider_velocity.dot(normal));
Simplified:
motion = motion - collision.normal * (collision.normal.dot(motion) - max(collision.normal.dot(motion), collision.normal.dot(collision.collider_velocity)));
Can it be further simplified? Probably, like I can just multiply the collision normal with max(0, collision.normal.dot(motion) - collision.normal.dot(collision.collider_velocity)), but that would be even more difficult for future me to understand, so...
Thanks for reading.
![](https://i.ytimg.com/vi/lBwgGriiwCE/maxresdefault.jpg)