I have a physics conundrum that’s been stumping me for a while now. I am building a game called SineRider which involves physically colliding with a graph. The function the graph is drawn from can include time variables, which means it can move.
The problem is that when the graph is moving, it doesn’t impart velocity on the sled. If a graph moves rapidly upward and then stops, you would expect the sled to be launched into the air. Instead the sled just sort of gets pushed out of the way, then stops with the graph. Here is an example of this behavior (press play when the game loads).
The reason for this is that the graph is not a moving rigidbody, but rather a static collider with a mesh that gets redrawn every frame. So even though the graph moves, it does not technically have velocity. Thus when the graph moves the sled, the velocity of the sled does not change.
I have been racking my brain for a way to fix this but have come up with nothing. If anyone has even a hackish workaround, I would be very grateful.
well one problem to consider. A graph as an abstract object, what mass would it have?
You can directly set the velocity of rigidbodies as well as turning off their gravity. And consider kinematic rigidbodies too, do research into that.
if all else fails, there’s always manual physics. Apply forces and set velocities of things when you think they should (generally when stuff is colliding)
I mean… this does not look so wrong does it. If I did something similar in reallife with a not bouncy material, I would expect what I see in your demo.
Nothing changes. The problem is that even if there is a rigidbody on the graph, it has no velocity because it is the mesh that changes and not the position of the object. So when the sled rigidbody collides with the graph, the collision is processed as inelastic and no velocity is imparted.
When happens if you instead create a box collider with a kinematic rigid body. Then set the x-position where your character is and the y-position to the function value on the graph. Maybe that will help, or we have to look at exposing a property for treating position changes as velocity. If it works you could create boxes for every object you need to collide with the terrain.
I tried this, but it’s a pretty weak solution since it only works properly for vertical motion. When the sled is pushed sideways by the graph you get weird behavior because the x position of the box is dependent on the player instead of the function. It also has problems when there are multiple dynamic objects on the graph, since they collide with each other’s ground boxes. I could set each object to a different collision layer, but you can see that this gets unwieldy pretty fast especially since collision layers are limited…
Would need experimenting, but maybe track your own velocity and apply back in?
Save position every FixedUpdate, compare current position this frame to last frame’s position for a velocity. The difference between this manual velocity and rigidbody.velocity should just be the position change due to the static collider pushing the object around. Apply that difference with AddForce with a ForceMode that ignores mass…?
I’m not 100% sure those two velocities would match up in normal circumstances, so maybe only apply if in contact with the graph, or recently in contact with the graph, etc…