Translation and Rotation

I was hoping to make the zucchini translate and rotate at the same time in code. I came up with a solution, but I am thinking there must be a better way to do this. The main problem I came across was that when the sprite is rotated, the translation will move in the direction of the rotation, which overall causes the zucchini to do a loop around the screen.

Here is the solution I came up for this, but it seems a bit forced. I would be interested to know if there is more of a built in Unity way to handle this.

public class Projectile : MonoBehaviour
{
    [SerializeField] private float projectileSpeed = 4f;
    [SerializeField] private float rotationSpeed = 100f;

    void Update()
    {
        Quaternion saveAngle = transform.rotation;
        transform.rotation = Quaternion.identity;
        transform.Translate(Vector2.right * Time.deltaTime * projectileSpeed);
        transform.rotation = saveAngle;
        transform.Rotate(Vector3.forward * Time.deltaTime * rotationSpeed);
    }
}

Hi Nathan,

First of all, good job on developing your own solution. :slight_smile:

You assign something to transform.rotation twice in your method. Then you call transform.Rotate. What exactly was your idea?

Instead of Transform.Rotate, you could test Transform.RotateAround because you actually want to have your zucchini spinning.

A little tip: Try to organise your code. At the moment, the code for the rotation and the code for the translation is mixed, which makes it a bit difficult to understand when skimming it.

1 Like

Hi Nina,

Thanks for the feedback! My idea was that the translation I want is relative to the orientation of the zucchini when it isn’t rotated at all. So, with these steps I:

Each frame:

  1. Save the current rotation of the object
  2. Set the object rotation to the identity
  3. Take care of the object translation, moving the object to the right a bit
  4. Return the orientation of the object back to what is was in step 1
  5. Rotate the object a little more than it was at the beginning of the frame

If I skip steps 1, 2, and 4, the problem I have is with transform.Translate(). Since the translation is relative to the orientation of the object, when the object is rotated a bit, the translation is in the wrong direction. For example, if the object is rotated 90 degrees, instead of translating to the right, it is translating down. So, when small rotations happen each frame, the zucchini actually ends up spiraling around a loop.

I looked at the documentation for Transform.RotateAround, and I am actually thinking that it wouldn’t quite solve my problem. The axis I want to rotate around is the center of the zucchini, and this method looks like it would make it easy to rotate around an alternate point.

The axis I want to rotate around is the center of the zucchini, […].

The centre is no axis. It’s a point. We call the point to which everything else is relative pivot point. The position values in the Inspector refer to the pivot point. In a Unity 2D game, you usually rotate around the z-axis, which goes “into” the screen.

You could try the following, which I didn’t test:
transform.RotateAround(transform.localPosition, Vector3.forward, rotationSpeed * Time.deltaTime);

Vector3.forward is shorthand for writing new Vector3(0f, 0f, 1f). The last component is the z-component. transform.localPosition is the pivot point. If the pivot point is in the centre of your sprite, your sprite should spin around its centre.

void Update()
{
    transform.Translate(Vector2.right * Time.deltaTime * projectileSpeed);
    transform.RotateAround(transform.localPosition, Vector3.forward, rotationSpeed * Time.deltaTime);
}

Depending on the position of the zucchini game object in your Hierarchy, you could use transform.position instead of transform.localPosition.

I gave this a shot, but it still gives me the looping. But, I started digging into the documentation and found that Transform.Translate can take a second parameter which defines the coordinate space the translation happens relative to. So, going with the code you gave me, and adding the Space.World parameter, I got it working with much cleaner code.

    void Update()
    {
        transform.Translate(Vector2.right * Time.deltaTime * projectileSpeed, Space.World);
        transform.RotateAround(transform.localPosition, Vector3.forward, rotationSpeed * Time.deltaTime);
    }

Thanks for the help Nina! :grin:

3 Likes

Well done! :slight_smile:

Does that mean, everything works as expected now?

Yes, it’s working as intended. Thanks again!

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms