# How to rotate several game objects without rotating individual objects

I have a some game objects that are a unit away from the center. They are all contained in a parent object, see the image below. When I rotate the parent object by 60°, the game objects individually rotate, as below. Below is the script attached to the parent object that I use to rotate the parent object.

    IEnumerator RotateSquaresParent(Vector3 byAngles, float duration)
{
Quaternion fromAngle = gameObject.transform.rotation ;
Quaternion toAngle = Quaternion.Euler (transform.eulerAngles);
toAngle = Quaternion.Euler (gameObject.transform.eulerAngles - byAngles);

for(float t = 0f ; t <= 1f ; t += Time.deltaTime/duration)
{
gameObject.transform.rotation = Quaternion.Lerp(fromAngle, toAngle, t) ;
yield return null ;

}
gameObject.transform.rotation = Quaternion.Lerp(fromAngle, toAngle, 1);

}


How can I rotate the parent object containing these square game objects without rotating them individually?

UPDATE

The squares represent enemy objects that would be shooting projectiles (yet to work on that) in my game. Thats why they'd have to be straight. As a player approaches a given child square (enemy), I would want to rotate individual child squares based on proximity and other conditions to possibly face the player object.

• How do you rotate the objects? From the editor? From a script? – Hellium Oct 9 '17 at 10:41
• @Hellium forgot to add that. I am rotating from a script. I just updated the question with the rotate coroutine. I also tried it manually, in the inspector and I got the same result. – SuperHyperMegaSomething Oct 9 '17 at 10:55
• If I understand correctly : you want to rotate the parent but keep the rotation of the children so that they are still "aligned with the screen"? – Hellium Oct 9 '17 at 11:00
• @Hellium Yes, in other words, I want to rotate the children by rotating the parent without the children rotating individually from squares to diamonds/aces like in the second image. – SuperHyperMegaSomething Oct 9 '17 at 11:06
• If you don't want objects to rotate together, then parenting might not be the right technique to use. Depending on what your ultimate application is, it could be more efficient to position the squares using trig or affix them to the rotating object using joints. What function are these squares and their movement serving in your game? – DMGregory Oct 9 '17 at 14:19

Try the following script :

IEnumerator RotateSquares( Vector3 byAngles, float duration )
{
int childCount           = transform.childCount;
Vector3[] localPositions = new Vector3[childCount];
Quaternion startRotation = Quaternion.identity;
Quaternion endRotation   = Quaternion.Euler( byAngles );
int childIndex           = 0;

// Store the local positions of the children
for ( childIndex = 0 ; childIndex < childCount ; ++childIndex )
{
localPositions[childIndex] = transform.GetChild( childIndex ).localPosition;
}

// Lerp position of children
for ( float t = 0f ; t <= 1f ; t += Time.deltaTime / duration )
{
for ( childIndex = 0 ; childIndex < childCount ; ++childIndex )
{
Transform child = transform.GetChild( childIndex );
Quaternion rotation = Quaternion.Slerp( startRotation, endRotation, t);
child.position = transform.position + rotation * localPositions[childIndex];
}
yield return null;
}

// Final position of the children
for ( childIndex = 0 ; childIndex < childCount ; ++childIndex )
{
Transform child = transform.GetChild( childIndex );
child.position = transform.position + endRotation * localPositions[childIndex];
}
}


I would save the rotation of the children and re-apply the initial rotation while rotating the parent.

    IEnumerator RotateSquaresParent( Vector3 byAngles, float duration )
{
int childCount = gameObject.transform.childCount;
Quaternion[] childRotations = new Quaternion[childCount];
Quaternion fromAngle = gameObject.transform.rotation ;
Quaternion toAngle = Quaternion.Euler( gameObject.transform.eulerAngles - byAngles );
int childIndex = 0;

for ( childIndex = 0 ; childIndex < childCount ; ++childIndex  )
{
childRotations[childIndex] = gameObject.transform.GetChild( childIndex ).rotation;
}

for ( float t = 0f ; t <= 1f ; t += Time.deltaTime / duration )
{
gameObject.transform.rotation = Quaternion.Lerp( fromAngle, toAngle, t );

for ( childIndex = 0 ; childIndex < childCount ; ++childIndex )
{
gameObject.transform.GetChild( childIndex ).rotation = childRotations[childIndex];
}
yield return null;

}
gameObject.transform.rotation = toAngle;
}


Otherwise, you may find a trick with the RotateAround function called on every child, and providing gameObject.transform.position as first argument

• @Helium, thanks, it's working, but I forgot to add an important aspect which I realized when I read DMGregory's comment, so I just updated the question. I hope that puts things a bit more in perspective. Your solution works, but it doesn't permit any of the child squares to be rotated individually. I was trying to rotate individual child objects (using my code above) whiles running the coroutine you provided, but the individual rotation was very brisk, running partially after the parent rotation was complete – SuperHyperMegaSomething Oct 9 '17 at 17:43
• @SuperHyperMegaSomething : I've update my answer, give it a try ;) – Hellium Oct 9 '17 at 18:40
• @Helium I would be very grateful if you could take a look at this question for me gamedev.stackexchange.com/questions/149689/… – SuperHyperMegaSomething Oct 19 '17 at 8:51

You cannot do this by applying a single transformation to the parent object because the desired end shape is not an affine transformation of the parent object.

I see the following options:

1. Rotate the parent object by X degrees around its center, and then rotate each child object by -X degrees around its center.

2. Discard the parent object, calculate the rotated position of child objects' centers and move the objects according to the change in their positions.