0
\$\begingroup\$

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.

enter image description here

When I rotate the parent object by 60°, the game objects individually rotate, as below.

enter image description here

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.

\$\endgroup\$
  • \$\begingroup\$ How do you rotate the objects? From the editor? From a script? \$\endgroup\$ – Hellium Oct 9 '17 at 10:41
  • \$\begingroup\$ @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. \$\endgroup\$ – SuperHyperMegaSomething Oct 9 '17 at 10:55
  • \$\begingroup\$ 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"? \$\endgroup\$ – Hellium Oct 9 '17 at 11:00
  • \$\begingroup\$ @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. \$\endgroup\$ – SuperHyperMegaSomething Oct 9 '17 at 11:06
  • 1
    \$\begingroup\$ 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? \$\endgroup\$ – DMGregory Oct 9 '17 at 14:19
1
\$\begingroup\$

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];
    }
}

INITIAL ANSWER :

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

\$\endgroup\$
  • \$\begingroup\$ @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 \$\endgroup\$ – SuperHyperMegaSomething Oct 9 '17 at 17:43
  • \$\begingroup\$ @SuperHyperMegaSomething : I've update my answer, give it a try ;) \$\endgroup\$ – Hellium Oct 9 '17 at 18:40
  • \$\begingroup\$ @Helium I would be very grateful if you could take a look at this question for me gamedev.stackexchange.com/questions/149689/… \$\endgroup\$ – SuperHyperMegaSomething Oct 19 '17 at 8:51
0
\$\begingroup\$

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.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.