Looking in the inspector under transform, I notice the x, y and z rotation are all varying, but the y-rotation is varying rather large. It looks like it is causing, the tilInZ variable in the Pin.IsStanding() to drastically change from 360 degrees to 0 degrees and back. This causes the IsStanding() to return false when the pin is standing straight on the screen.
This happens because unity doesn’t go on to negative numbers for the rotation, so you have to write some code to test the other way too, something along the lines of (in pseudo code)
If tilt > 360-threshold then
Return true
You will need to do this for your x and z tilts of course
To this day I don’t know how Ben got it to work without adding this.
On a further note, if your pins are constantly wobbling, try lowering your gravity by a fair amount, it will probably stop, it’s annoying that it does this if you want real physics, it probably works better if you know how to deal with it with physics materials or something lol
The main problem here is that we are using Vector3 to handle rotations, which is not advised since Internally unity uses quaternions, that are made for that, and would be a more suited solution in this case.
The method Quaternion.Angle(Quat a, Quat b) returns the angle between two rotations, so you could store the initial rotation on the start method (Quaternion x = pin.transform.rotation) and than compare it to see if it is still standing:
If (Quartenion.Angle (x, pin.transform.rotation) >= Angle threshold) DoThis;
This doesn’t solve it, because it seems the number span the entire 360 degree range. It just decreases from 360 degrees until it goes to zero and wraps around to 360 and repeats.
However, somebody else mentioned to try and reduce the default solver iteration to 25, and that seemed to have worked, but why would that affect angle?
Not sure, it’s a strange one. the physics seem to just go insane when you have the gravity up high and the number of resolvers low, I had a similar issue, but you could see the pins shaking like it was freezing cold
I know its an old topic, but I’m pulling my hair out at this one too. I’m seeing rotations and wobbles with my pins everywhere which are messing up my IsStanding calculations. But then I didn’t really understand Euler Angles earlier.
I’m convinced there are two problems - One related to the refactoring of the pins themselves and that their axes are not aligned with the world, and the other in the physics.
I found with the physics that increasing the sleep threshold significantly in the project settings seemed to help with the wobbles a lot (mine is 5 now) - but still not enough with full gravity (-981), and still not a solution to the rotations.
Ok so i dig into this problem.
I have changed pins like Ben in course, this new pins should have diffrent axis (all pins have now ‘x=-90’ rotation on start). This will have many repercussions on how they work
In my opinion:
In ‘IsStanding’ method only ‘x’ axis matter.
In ‘Raise’ method should be code that reset position and velocity of pin
In ‘RenewPins’ when you instantiate pins you shold move whole parent up by distance to raise
My code is slighty changed to yours but i belive you will get what i am trying to explain.
Moreover i didnt delete any animations states.
My ‘Tidy’ state work as follow: raise,swipe,lower,exit
My ‘Reset’ state work as follow: swipe,renew,lower,exit
My physics values:
Gravity 98.1
Bounce treshold 200
Sleep Threshold 0.5
Default Contact Offset 1
All bjects have default physcis material
Blockquote
// Check if pin is standing.
public bool IsStanding()
{
// Get rotation of pin in Euler angles.
Vector3 rot_in_euler=this.transform.rotation.eulerAngles;
// Get tilt values of pin (‘y’ and ‘z’ is irrelevant for checking if the pin has been knocked over).
float new_x = 270.0F - rot_in_euler.x;
float tilt_x = (new_x<180.0F) ? new_x : (360.0F-new_x);
// If tilt values did not exceed treshold then return TRUE;
if(tilt_x<this.standing_treshold)
{
return true;
}
// Return FALSE.
return false;
} // End of IsStanding
Blockquote
// Raise pin.
public void Raise()
{
// If pin is not standing then exit from function.
if(!this.IsStanding())
{
return;
}
// Disable gravity on pin.
this.rbdy.useGravity=false;
// Reset position and rotation of pin.
this.transform.position=this.start_pos;
this.transform.rotation=this.start_rot;
// Reset physical values of pin.
this.rbdy.velocity=Vector3.zero;
this.rbdy.angularVelocity=Vector3.zero;
// Raise pin.
this.transform.Translate(new Vector3(0.0F,PinsSetter.distance_to_raise,0.0F),Space.World);
} // End of Raise
Blockquote
// Renew pins.
public void PinsRenew()
{
// Destroy old pins parent.
Destroy(this.pins.gameObject);
// Instatniate all pins.
this.pins=Instantiate(this.pins_prefab,this.pins_prefab.transform.position+Vector3.up*distance_to_raise,Quaternion.identity);
// Loop through pins.
foreach(Pin pin in this.pins.GetComponentsInChildren())
{
// Disable gravity on pin.
pin.GetComponent().useGravity=false;
// Raise pin.
pin.transform.Translate(new Vector3(0.0F,distance_to_raise,0.0F),Space.World);
}
} // End of PinsRenew
All work fine for me.
If anybody want here is link for my repo: Repo