- Home /
ConfigurableJoint Anchors and nested RigidBodies
My game includes "tank" vehicles, which contain six independent tracks. Each tank has a RigidBody component. The tracks, which are children of the tank, each have their own RigidBody component as well. The tracks also each have a ConfigurableJoint which connects them to their tank.
On local tank instances, the setup works beautifully! A script attached to each track adds forces to it based upon the player's input, and the tank glides over even the roughest terrain.
On networked instances of my tank, things aren't working so well. My networking code directly alters the transform.position of the tank object to match it to it's position to it's authoritative instance on another client. Although the tank's tracks get drug over the terrain quite nicely, they begin to drift off after a while. The longer a networked tank drives around, the farther it's tracks drift away from it in random directions. It looks like some kind of rounding errors in each track's joint's anchoring calculations accumulate over time and it forgets where it was supposed to be positioned relative to it's parent tank.
I thought this would be an easy problem to solve, and I wrote the following code and attached it to each track to manually reassign the track's ConfigurableJoint anchor each physics frame:
var strtPos : Vector3;
function Start() { strtPos = transform.localPosition; }
function FixedUpdate(hit : ContactPoint, collision : Collision) { joint.anchor = transform.InverseTransformPoint(transform.parent.TransformPoint(strtPos));
}
Unfortunately - instead of ensuring that each track doesn't wander off, the above code sends each track careening off into the sunset almost immediatley.
You can witness this behavior firsthand in the latest test build of my game: http://dat.marsxplr.com/213/play Start two game instances and connect them to each other, switch to a tank in both, drive around for a bit in one, and then drive near your first tank with the other. The longer you drive around, the more messed up your tracks will look on other networked clients. (note that tracks on distant tanks aren't simulated, you need to drive near a tank to see it's "real" rigidbody tracks).
Please let me know what could be causing the joint anchoring issue in the first place, and what I can do to circumvent it!
Interesting! I was just able to deter$$anonymous$$e that the treads loose their anchor position not randomly over time, but specifically when their GameObject's are disabled and re enabled again. In order to maximize performance, I have been replacing the physics intensive tracks on network tanks with simpler ones that are swapped out when the tank reaches a certain distance from the camera. Ins$$anonymous$$d of just disabling and re-enabling the tracks, I will try rebuilding them from scratch as necessary. This should solve the problem! Have I discovered a bug in Unity's physics engine, or is this expected?
Answer by Aubrey-Falconer · Dec 23, 2009 at 04:52 AM
Problem solved!
When the GameObjects that ConfigurableJoints are components of are disabled and later re-enabled, the joints get totally messed up.
This code solves it:
function Start() { strtPos = transform.localPosition; }
function OnEnable () { if(strtPos == Vector3.zero) return; transform.localPosition = strtPos; transform.localRotation = Quaternion.identity; joint.anchor = Vector3.zero; }
Answer by CJCurrie · Dec 23, 2009 at 12:43 AM
Hi,
First off, your backend looks to operate beautifully, with a lot of features without a lot of system overhead (for the most part). However, I wasn't able to see how to instantiate the tank objects (I saw the options to enable tanks, though), so I couldn't examine your problem. It sounds from your description that the configurable joint is being displaced during the authoritative update. Have you tried using rigidbody.MovePosition() instead of altering transform.position (since you are using a huge amount of physics)?
-CJ
Thanks! rigidbody.$$anonymous$$ovePosition was a great idea, but rewriting my networking code to use ins$$anonymous$$d of altering the position of the tanks's Rigidbody directly didn't help my tank tread objects stay anchored to where they should be on networked tanks. To switch to a tank in $$anonymous$$ars Explorer, just drive near the glowing white "start point" in each world and a Switch Vehicle dialog will appear. Has anyone ever experienced joints that loose their anchor over time, and any idea why my script to manually reanchor each tank tread isn't working?