I’m working on a project where a rigid ball is hitting multiple rigid castles made of small rigid bodies.
But I had a problem with sleeping and waking up rigid bodies.
Here is my problem:
- My rigid-body sleep function only works for the first object that is instantiated. For later instantiated objects, the sleeping rigidbody will still move.
Here are my codes:
-
This code is placed on Main Camera
void StartLevel()
{
//如果城堡已经存在,则清除原有的城堡
if(castle != null)
{
Destroy(castle);
}
//清除原有的弹丸
GameObject[] gos = GameObject.FindGameObjectsWithTag("Projectile");
foreach(GameObject pTemp in gos)
{
Destroy(pTemp);
}
//实例化新城堡
castle = Instantiate<GameObject>(castles[level]);
castle.transform.position = castlePos;
shotsTaken = 0;
}
There is a complicated issue at work here. My guess is that it’s related to how Unity handles transform updates. When you do
transform.position = something;
Unity doesn’t immediately update the entire object (like informing the colliders about the updated position). Instead, all transforms that have been changed in a frame will be collected, and their updates will be handled at the end of the frame. This way, if you change the position of an object twice in a row, or the position and the rotation, Unity won’t be recalculating everything twice, but only once.
What also happens at the end of a frame is Start, where you send your Rigidbody to sleep. It seems that Start comes first, and the transform updates after, meaning that the Rigidbodies are moved after they’re send to sleep. My guess is that that wakes them up again.
There is a simple fix that worked for me while reproducing this: Set the position in the Instantiate call.
Instead of
castle = Instantiate<GameObject>(castles[level]);
castle.transform.position = castlePos;
do
castle = Instantiate<GameObject>(castles[level], castlePos, Quaternion.identity);
This will apply the position right away, so the Sleep() call will definitely come afterwards.
Also, you can omit the <GameObject>
part:
castle = Instantiate(castles[level], castlePos, Quaternion.identity);