Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Spring Joint Collisions Don't Work With Children?

Discussion in 'Scripting' started by John-B, Apr 20, 2014.

  1. John-B

    John-B

    Joined:
    Nov 14, 2009
    Posts:
    1,259
    I'm using a sprint joint attached to a parent object to drag it around. The parent is an empty object with just a rigidbody attached. The children each have both a collider and rigidbody. Kinematic and trigger are all set to false when dragging. The static objects in the scene all have colliders only (no rigidbodies) trigger set to false. The dragging works fine, but the dragged object doesn't cause collisions with other (static) objects in the scene. This is the exact same code and spring joint I use to drag the camera around, and it works as expected - it stops when it hits a wall.

    The only differenceI can see is that the camera has both a collider and rigidbody and no children, while the parent object being dragged has no collider. Does the parent object being dragged by a spring joint need to have a collider? I can't really add one without some major script changes (I tried), so I hope that's not the case. That could cause other problems as well, since the parent object can have a variable number of children, and any collider attached to the parent would need to be resized/repositioned frequently.
     
  2. John-B

    John-B

    Joined:
    Nov 14, 2009
    Posts:
    1,259
    I did try temporarily adding a collider to the parent just while dragging, but I don't know if that fixed the collision problem. It totally screwed up the dragging, the object went flying off.
     
  3. John-B

    John-B

    Joined:
    Nov 14, 2009
    Posts:
    1,259
    Looks like the problem is with the collision matrix, what collides with what. The parent object, while being dragged is not kinematic, but the children are kinematic. The children have to be kinematic while dragging or they won't follow the parent. But it looks like kinematic rigidbodies only collide with non-kinematic rigidbodies. And the walls and other objects are static colliders, no rigidbodies. If I add rigidbodies to the walls, they have to be kinematic, and so won't collide anyway.

    So now I don't know what to do. I can't find any combination that lets me drag the parent with a spring joint and have the children both follow and interact with other objects. Any suggestions?

    Also, I still don't know why adding a collider to the parent screws up the dragging. Whether I add it permanently or just during dragging, if the parent has a collider, it flies off into oblivion as soon as dragging starts.

    I also tried adding non-kinematic rigidbodies to the walls, assuming they would rest on the floor, but they just fall right through. I have no idea why, since a rigidbody collider should collide with anything that's not a trigger, at least according to the matrix.
     
    Last edited: Apr 21, 2014
  4. rrh

    rrh

    Joined:
    Jul 12, 2012
    Posts:
    331
    Let me try and get straight what you've got going on here.

    You've got Joe, and Joe is just a rigidbody, no collider.
    Joe has children, and they have rigidbodies and colliders.

    Joe has a spring joint, and you're changing the properties of the spring joint to move the position of Joe.


    My first thought is to just remove the rigidbodies from all the children of Joe. Leave the colliders. Like, you're doing all this work to counteract what rigidbodies do, so maybe just make them not rigidbodies.


    If it is absolutely crucial that all the children are also rigidbodies, my second thought is assign them all their own Configurable Joints attached to Joe and use those to keep them following it.
     
  5. John-B

    John-B

    Joined:
    Nov 14, 2009
    Posts:
    1,259
    That about sums it up.

    The children DO need both rigidbodies and colliders. When they're not being dragged around as a group, they need to act/respond independently. The user manipulates them as a group, then physics takes over when they're released. And as far as I can tell, there is no way do disable a rigidbody, like you can with pretty much everything else. But I'm not sure that the children having rigidbodies is the problem.

    I thought about attaching each object to the spring joint (can you have more than one connectedBody?), but I thought they'd probably not maintain their relative positions while dragging. Springs tend to lag and bounce a bit. If each child object would require its own spring joint, that could be messy, as there are between 10 and 50 children in each group (Joe can be very prolific).

    I had been using triggers for dragging, and wanted to use physics instead. The result is better, the movement is smoother and eases in/out, and I was spending a lot of time tracking down which triggers should be set how and when.
     
    Last edited: Apr 22, 2014
  6. rrh

    rrh

    Joined:
    Jul 12, 2012
    Posts:
    331
    You could use FixedJoint or something to be less bouncy.

    You don't assign multiple connectedBodies to Joe's spring joint, you'd assign a joint to every child and connect them all to Joe.


    I suppose another approach would be to store an array of locations localPositions for the children when you start dragging, turn them all kinematic and then while dragging use Rigidbody.MovePosition to move them to that position relative to Joe. That probably does have good odds of a collider knocking Joe out into the distance, I dunno.
     
  7. John-B

    John-B

    Joined:
    Nov 14, 2009
    Posts:
    1,259
    MovePosition doesn't work with rigidbody collisions. It doesn't stop when it hits a collider, you still need a trigger. That's pretty much back where I started. I'm trying to avoid using triggers and do everything with physics. I don't think I can though.

    What seems to work best (not perfect) is using a combination of the two. I'm using a spring joint dragging the object to get nice, smooth movement, and triggers to determine when to stop moving. I'm not happy, but at least it's an improvement, for now.
     
  8. rrh

    rrh

    Joined:
    Jul 12, 2012
    Posts:
    331
    Oh, I was confused. I just tested, and MovePosition respects collisions if it's not kinematic, but somehow I got it in my head it still worked when it is. So imagine I said the same thing without turning the children kinematic.
     
  9. John-B

    John-B

    Joined:
    Nov 14, 2009
    Posts:
    1,259
    MovePosition affects objects the moved object collides with, but does not affect the moved object, presumably, as you said, because the moved object is kinematic.

    Anyway, I got this working to the point I can live with it. It works fine, but not for all objects. I have a variety of objects with different numbers and arrangement of children. They all drag the same except for two object types.

    One drags MUCH more slowly than the others, with considerable lag. It doesn't appear to have anything to do with the number of child rigidbodies or their masses. Actually, this is one of the simplest objects. Only three of its children have rigidbodies, while some have up to 50 children with rigidbodies. Luckily, it was easily fixed by decreasing the spring joint's damper to close to zero.

    The other object that doesn't work behaves completely different than the rest. It appears to move in a direction opposite the spring joint, at least at first. If I continue dragging it, it eventually changes direction to match the dragger object, but is always offset from it. This object is a little more complex with children of children, but so are others and they work. I have no idea what the problem is with this one object type.
     
  10. John-B

    John-B

    Joined:
    Nov 14, 2009
    Posts:
    1,259
    I figured out why the one object behaved differently than the others. Two of its children's rigid bodies were slightly overlapping in their initial positions. I resized and moved them slightly, and now it works!