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\$
6
  • \$\begingroup\$ How do you rotate the objects? From the editor? From a script? \$\endgroup\$
    – Hellium
    Oct 9, 2017 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\$ Oct 9, 2017 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, 2017 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\$ Oct 9, 2017 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, 2017 at 14:19

2 Answers 2

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\$
3
  • \$\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\$ Oct 9, 2017 at 17:43
  • \$\begingroup\$ @SuperHyperMegaSomething : I've update my answer, give it a try ;) \$\endgroup\$
    – Hellium
    Oct 9, 2017 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\$ Oct 19, 2017 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\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .