Godot Version
4.6.1
Question
TLDR: Specific questions below. The text here provides background and details of my experiments.
I’m interested in implementing a physics-based object dragging mechanic in the style of HL2 and Amnesia. I’ve tried several approaches, including using:
rigidBody.ApplyForce((targetPosition - rigidBody.GlobalPosition) * someMagicNumber)
custom PID controllers, and SpringArm3D.
All of these methods have significant drawbacks that can only be ignored if the required result doesn’t need to be very precise. The main problem is that the held object either follows the pointer too slowly or interacts unrealistically with other physics bodies, colliding heavily with them or even passing through walls.
A more “proper” approach seems to be using constraints/joints. They ensure correct physical behavior and require minimal code. However, the same dilemma remains: either the object follows the pointer too slowly, or it interacts unrealistically with other bodies. For example, with a stiff LinearSpring/LinearLimitSpring on a Generic6DOFJoint (Godot Jolt Extension), movement becomes very responsive, but lightweight objects strongly push heavier ones. Making the spring softer makes interactions more predictable and “realistic”, but the responsiveness is reduced.
I’ve tried splitting movement into two states: free, without contacts and with a stiff spring, and a soft spring during collisions. This didn’t achieve the desired result. Adjusting max_force on all axes (linear_spring_x/max_force) caused the held object to sag along the Y axis, even though it was only supposed to be constrained in the XZ plane, and apply weaker forces to other objects. Attempts to change max_force locally, for example depending on the collision normal, also didn’t solve the issue. Additionally, object mass must be considered. Simply juggling numbers in the hope of finding the right configuration doesn’t work. The current situation is: a light object can push a heavy one too strongly, while simply limiting the held object’s velocity makes movement feel “dead”.
Specific questions:
- Does the position of the joint and static_body nodes (with static_body used as node_a in the joint) in the scene tree matter?
- Is it possible to solve this issue without writing a custom Constrain Solver, using only the capabilities of Generic6DOFJoint?
- Are there any publicly available examples of how similar mechanics are implemented in other games?
Any advice or guidance is appreciated — I’m mainly looking for directions to explore further. It feels like I’m missing a small detail that could make everything fall into place.