- Home /
How to let a GameObject generate force but not be affected by certain forces?
tl;dr Without using a kinematic Rigidbody, how do I enable some GameObject A to move some GameObject B, but disable B to move A? (Looking for a "force diode".)
I am making a 2D local co-op game where players work together to move objects around or rotate them. My current solution to achieve this is as follows.
The objects have one ore more 'attachment points'; when a player is on top of such an attachment point, he can attach himself to the object, meaning the attachment point will not move relative to the player nor the object, but rotation is still possible. To paint a clear picture: it's like hammering a nail through the attachment point on the object, through the player as well.
I do this by, upon attaching, adding a HingeJoint between the Rigidbody of the object (which is, in terms of GameObjects, a parent of the attachment point) and the player. A HingeJoint is a constraint between two Rigidbodies, so my player GameObject must have a Rigidbody as well.
However, because my player GameObjects now have a Rigidbody, they are affected by certain forces I do not want them to be affected by. For example, when two players attach themselves to the same object and only one starts moving, the other one will move as well (involuntarily) because their Rigidbodies are both constrained to the same Rigidbody, being the Rigidbody of the object they attached themselves to.
What I want is that players cannot be moved unless it is voluntarily (by user input) or by collision response (players shouldn't be able to move through certain GameObjects, like walls). This is exactly what a CharacterController can provide for me, but because of the way I attach players to objects I also need a Rigidbody. Making players kinematic and somehow make them not go through walls would not solve the problem as having two kinematic Rigidbodies constrained to the same Rigidbody with Joints causes the Joints to simply explode.
On top of that, entities other than players are supposed to be able to attach to objects as well, using the same attachment points. Think of the player attaching himself to a key, carrying it to a keyhole, where the keyhole then attaches itself to the key. The floor attaches itself to one end of a long object, the other end has an attachment point for the player to work with; a lever. I would really like to maintain a generic solution such that the endless possibilities of this attaching system will remain. Currently I do this by having an Attacher interface make attachment requests to the AttachmentPointController component of the attachment points. Via this interface the attachment point asks where the Joint should be anchored on the Rigidbody of the Attacher. Anything with a Rigidbody can then start attaching itself to objects by simply implementing the Attacher interface.
This attachment point using a Joint and an interface approach seems like the way to go, except for the fact that players are involuntarily moved because of these Joints. Is there any way to keep the Rigidbody on players yet not make them move involuntarily? Perhaps if I could somehow disable players to be affected by Joint forces, but still enable them to generate Joint forces?
Ideally I'd find a solution that allows me to keep using Rigidbodies for my players, but if there is no other way to stop my players from moving involuntarily I am willing to switch to CharacterControllers, meaning I will likely also have to abandon my point-joint-interface approach. Are there any CharacterController solutions that still allow me to have a generic solution to let entities attach themselves to objects?