Wobbling Pins? - Things To Try

If you’re having trouble with wobbling pins in this lecture, here are a few things to try…

Change Gravity

Go to Edit > Project Settings > Physics. Try other values for gravity ranging, for example -9.81, -98.1 or -981.

Iteration Count

Change the physics iteration count, 10 has worked for some.

Collision Detection Type

Try continuous vs discrete collision detection.

This post is a wiki, so you can edit it to make it a better reference :slight_smile:

2 Likes

Potential Solution 1

In Unity: Edit > Project Settings > Physics. Set gravity to -98.1. And in Pin.cs:

void Awake () {
    this.GetComponent<Rigidbody>().solverVelocityIterations = 10;
}

If 10 does not work, increase the value. For some worked 23. For further information on solverVelocityIterations see the docs.

As an alternative, you could give Rigidbody.solverIterations a try:

 void Awake () {
     this.GetComponent<Rigidbody>().solverIterations = 10;
 }
2 Likes

Thank you so much!!

I recently had the same issue but was confused as what to try first so I did a little experimenting.

I would summarise this thread as follows:-

Edit/Project Setting/Physics will open up the Physics Manager. This will allow you to amend some values that are game WIDE i.e affect every rigidbody in every scene for the whole project.

You might remember that we set the Gravity Y scale to -981 as Ben was scaling his game from Unity Meters to Unity Centimeters for the unity Unit. I wouldn’t amend this yet. The other options i this thread refer to ‘Default Solver Iterations’ and 'Default Solver Velocity Iterations.

For me setting the value Default Solver Iterations to 14 worked, any less, and the odd pin reports a false boolean. Any more and you can affect the performance. I would suggest that any variations for this number will be due to system specifications etc etc etc. Therefore, I’d recommend setting this to a value like 50 and work down, remembering to do a bit of a soak test.

Once you have a value that you are happy with you should then set it back to the default of 6. Reason for this is the default Physics setting works for all rigidbodies in the project. Why affect a global variable, when everything is working except for a few pins.

This is where the code is useful, i.e on awake for each pin override the value and this will mean you’ll only target the 10 pins. This will be more performance friendly.

Others may like to add to the debate but for now I would ignore the -98.1 suggestion and the adjustment of the rigidbody collision detection value.
Lee.

When I came across this issue there was a recent question asked here. I investigated reasons for rigidbodies vibrating or handling physics collisions poorly and in the end came back to the Unity manual page on Rigidbody which states that

Use the right size

The size of the your GameObject’s mesh is much more important than the mass of the Rigidbody. If you find that your Rigidbody is not behaving exactly how you expect - it moves slowly, floats, or doesn’t collide correctly - consider adjusting the scale of your mesh asset. Unity’s default unit scale is 1 unit = 1 meter, so the scale of your imported mesh is maintained, and applied to physics calculations. For example, a crumbling skyscraper is going to fall apart very differently than a tower made of toy blocks, so objects of different sizes should be modeled to accurate scale.

This seemed to indicate that our use of 1 unit being 1cm is the cause of the issue. To test this, I did the following:

  1. Add everything in the scene to an empty GameObject
  2. Set the scaling of that GameObject to 0.01 in all dimensions
  3. Reverted gravity to -9.81
  4. Made the move arrows nudge by ±0.05

This solved the issue and is in my view the best way to solve the problem since it addresses the root cause in accordance with Unity’s documentation and best practices.

2 Likes

Thanks for the tips there Dave, after doing that and messing with the maximum angular velocity on my ball, it started playing like a real bowling game should feel.

However it’s not just the case of messing with the nudge, you also have to adjust your drag amounts by /100, alter camera max positions, readjust your top camera, adjust the positions where things are reset to like the ball etc, amongst other things, but the biggest problem is when the pins reinstantiate after a reset, they are their original size, even if you parent them to the empty GameObject. So I think the only real way to solve this is do it properly and go through everything and resize the lot properly instead of messing about sticking it all inside an empty GameObject. It’s a good hours worth of work (probably), but I recon it’d be worth it in the end.

Hi there,

I went back and looked at this again as I couldn’t remember any issue with scaling. You were right and I forgot to add a step to my advice. I added a script component called Holder to my empty GameObject. This script ended up not actually doing anything, but I then used it to find my Holder object when my PinSetter instantiated a fresh set of pins, so that I could set the holder as parent like so:

public void RenewPins() {
	GameObject pins = Instantiate (pinSet, FindObjectOfType<Holder> ().transform) as GameObject;
	pins.transform.localPosition = new Vector3(0f,45f,-38.7865f);
	foreach (Rigidbody r in pins.GetComponentsInChildren<Rigidbody> ()) {
		r.useGravity = false;
	}
}

It’s a little rough around the edges now that I look back at it. Apologies for not including that step earlier.

I don’t believe I had to change too much else, but that may be due to how I scripted my cameras. My cameras are both childed to the Holder GameObject, in case that is an issue. I did have to adjust how I read the power of a drag, but I considered that to be a matter of personal preference anyway.

I do agree that the most correct way to make the game is to use Unity’s scale from the beginning, but it’s an imperfect world. I still feel my workaround is the best option for anyone not wanting to repeat a lot of work at a different scale in order to progress through the lectures.

Sorry again for not including my method of resetting pins in my initial post.

Don’t sweat it, you’ve done a great job with your solution :slight_smile: thanks for adding in the extra step!

Hi All,

Another solution for this issue by using Animation.

After tried to use many methods to stop the wobbling pins. I’ve found that the easier solution without changing any settings is add animation to Idle state and add some event, so I can set freezeRotation on LowerState and reset it to default after exit to Idle.

Here is my final solution to solve this issue, it work out for me and still not found any problem yet.

Code added on PinSetter.cs:

public void PinsIdleState () {
        // Reset to default value when all pins settled down
        Pin pin = GameObject.FindObjectOfType<Pin> ();
        pin.ResetPin ();
}
 
public void RenewPins () {
        GameObject pins = Instantiate (pinSet, new Vector3(0, distanceToRaise, 1829), Quaternion.identity) as GameObject;
        foreach (Rigidbody rib in pins.GetComponentsInChildren<Rigidbody> ()) {
            rib.freezeRotation = true;
        }
}

Code added on Pin.cs:

public void Lower () {
        transform.Translate (new Vector3 (0, -distToRaise, 0), Space.World);
        rib.useGravity = true;
        rib.freezeRotation = true;
 }
 
 public void ResetPin () {
        if (gameObject) {
            rib.freezeRotation = false;
            rib.useGravity = true;
        }
 }

Hope this help anybody whom finding solution on pin wobbling issue.

1 Like

Thanks - solution 1 worked for me - BUT I really think the whole Bowlmaster section needs this “bug/physics limitation” information in a much clearer position.
Even today when using versions of Unity from late 2018/start 2019 this is still an issue (“feature”).
Otherwise we all waste a lot of time trying to figure out why things are not working as expected.
Thanks for otherwise great course!!

Privacy & Terms