I have an object I control with RigidBody3D and apply_central_force, and whose rotation and Z position are all locked. This works very well for a 2.5D game. However, in lieu of setting the object down on top of other objects or static colliders I am casting a ray downward and applying spring and damper forces which allow it to hover very close to other objects without touching them. I am using a primitive “friction” that slows the object, basically just continually decreasing its X velocity if the ray is hitting an object. This is physically incorrect but was good enough for the game as it was.
The problem is now that the object must “land” on a moving platform. The moving platform is an AnimatableBody3D being moved with a PathFollow3D. The flying object interacts with it as expected, its rays detect it and it hovers above it, but it doesn’t follow the motion of the platform, for obvious reasons. I need this body to act as if there is a contact point between them without there actually being a contact point. I would like to simulate friction in a realistic way, such that if the platform moves slowly the static friction is not overcome and the hovering object rides the moving platform, but if the moving platform accelerates too quickly the hovering object should slide.
I’m not good with physics. I’ve been reading (terms like coefficient of friction, normal force, etc are familiar to me now), but nothing I try seems to work right. Part of the problems I think is that the AnimatableBody3D has no velocity, so I’m trying to calculate the velocity based on its previous position, but the results seem to be unpredictable. I have everything running in physics update, including the animator that’s moving the path follower, so everything should be in sync there.
I was really hoping there would be a way to just fudge this and add a fake contact point based on the raycast and let the physics engine do its thing. Barring that, I need to duplicate what the physics engine is doing and apply the correct forces myself.
Thanks, but I had tried that and honestly couldn’t get it to do anything but explode. I have a feeling I was using it wrong, but I also don’t have a lot of confidence in the Godot physics engine and don’t know exactly what the issue was.
I’ve ended up solving this in a completely different way: using only a single collider for the player and simulating the spring physics only graphically. When the player lands I note the velocity, set that in my own internal simulation of the hovering and add fake forces to a fake physics body to make it look right. Now the player can ride platforms as expected without any special logic.
Simple solution: Have a child of your animatable body that collides only with moving platforms and has a certain in-engine friction or whatever values necessary to keep it stuck to the platform if their velocities are similar enough.
Alternative solution:
When you detect you’re on a platform, check the velocity between the platform and your object, and then add the difference between the platform and your objects velocity to the objects velocity (preferably before any other physics input from the engine, so you don’t just permanently get stuck)
Put a maximum limit on the velocity added to the object; if the platforms speed goes beyond that velocity, only add the limit; now the object will slide off as the platform accelerates out from under it.
Now that the player is a rotation-locked cube you’d think that friction would stick them to the platforms, but it only works on very slow-moving platforms. It doesn’t matter how high I make the friction the player slides off if there is enough fake acceleration from animatable body. It also doesn’t help that the fake acceleration from the moving platforms seems to lag behind its actual movement.
Right now if the player is on top of a moving platform and the relative velocity is low enough I put a pin joint. The player can’t move left or right while on the ground anyway, so this works, and I just disconnect the joint when the player jumps. But the player’s velocity never actually gets low enough on platforms that always change direction, if I set the threshold too high the pin joint stops the player unnaturally.
Okay, I was just being stubborn. CharacterBody3D does everything I need in terms of movement including riding platforms since it was designed to do that, I should have been using that in the first place. I can just simulate the spring physics visually and now everything works fine.