Search Unity

Question How to prevent a heavy rigidbody object from penetrating another?

Discussion in 'VR' started by vrjoydev, Mar 6, 2023.

  1. vrjoydev

    vrjoydev

    Joined:
    Nov 7, 2018
    Posts:
    5
    I'm developing a multiplayer Jenga game, I'm having difficulty stacking a large amount of bricks, even controlling gravity and the mass of the objects, the bricks at the bottom of the pile end up penetrating each other, knocking the pile down.


    upload_2023-3-5_21-26-18.png

    upload_2023-3-5_21-27-17.png
     
  2. halley

    halley

    Joined:
    Aug 26, 2013
    Posts:
    2,443
    You are probably going to have a very hard time with this level of fidelity from the physics simulator. It's good for a rough simulation of a bunch of items but can get freaked out by the slightest nudge in a way that real Jenga tiles won't.

    I suggest you keep all the rigidbodies isKinematic=true and slightly undersized from the spacing of the tower blocks. Measure the grab/push/poke forces of players' hands yourself. Animate some swaying motion in a cartoony fashion depending on how stable or unstable you think the tower should be at each level. When your players have gone too far, nudged too hard, or removed a supporting block, turn off the isKinematic flags, and let the physics system do the job of toppling the whole tower in a pseudo-realistic way.

    Sounds like a great party game. Be careful of the Jenga trademark and you'll be popular.
     
    nilagard and vrjoydev like this.
  3. vrjoydev

    vrjoydev

    Joined:
    Nov 7, 2018
    Posts:
    5
    Thanks for the feedback,
    I've developed a solution that works, but I'm not sure it's best practice.
    When I spawn the bricks in the scene, I change their mass proportionally to the Y axis, so the mass of the bricks decreases as they get higher in the tower.
    I also calculate the mass once the brick is dropped on top.
    Apparently it's working very well.

    thisObject.GetComponent<Rigidbody>().mass = 30-(thisObject.gameObject.transform.position.y*20f);