Rotating in Unity
I thought it was simple. I was wrong.
I’m working on my (first) game in Unity, Space Short (10 levels, two bosses, no distractions. Can you make it to the end?). In the first 4 levels, there is one kind of enemy spaceship that moves down towards the player (called Enemy 1). In the levels after the first boss, there is a second type of enemy spaceship, that moves from the side (called… Enemy 2. Obviously).
So I created the Enemy 2 prefab, that moves from right to left. I thought it would be pretty obvious to rotate it by 180 degrees and have it move from left to right.
Previously, I rotated my lasers using Quaternion.
for (int i = 0; i < numMissiles; i++){
tmp = gameManager.bossLaserPool.Get();
tmp.transform.position = transform.position;
tmp.transform.rotation = Quaternion.Euler(0, i * 22.5F, 0) * tmp.transform.rotation;
}
While I didn’t really understand why I needed a Quaternion with half my desired angle, or what a Quaternion even is, I thought whatever, and used it anyway.
It worked perfectly, though. I rotated using a Quaternion, and then my forward was in the correct direction and each laser (or missile) moved in the direction of their transform.forward
.
I just figured I would do the same with my Enemy2: Define the direction of the Enemy2 Prefab such that its transform.forward
is in the direction of the spaceship front; rotate it by half the angle I need, that is 90 degrees ; have it move in the direction of its transform.forward
.
//movement - in EnemyController
movementDirection = transform.forward * stepSize;
transform.Translate(movementDirection);
//rotation - in SpawnManager
GameObject enemy = gameManager.enemy2Pool.Get();
enemy.transform.rotation = Quaternion.Euler(0, 90F, 0)*enemy.transform.rotation;
The result was… odd.
Part of the problem was that I originally used the Quaternion as is without multiplying it by transform.rotation
, though surprisingly that wasn’t the main issue.
So what was I missing?
First, for general understanding, I found this great video by 3blue1brown that explains what quaternions are. There is an entire series. These videos are great because instead of throwing the equations at you (as most definitions of quaternions do) 3blue1brown explains what it actually means.
Then I found this gem by gamedevbeginner, that explains about the various rotating methods and when to use each. And one of the important takeaways is this:
Quaternions are complex and aren’t designed to be worked with directly.
In addition, I needed to clarify for myself what transform.forward
actually means — it’s not as though Unity knows which direction for my spaceship is ‘forward’. It takes the local z axis of the object. What I also missed is that transfrom.Translate()
is already in the local coordinates, so in effect I was using transform.forward
twice: once in movementDirection
and once in transform.Translate()
.
So what did I do wrong? Basically everything. I used the wrong movement, I rotated using a quaternion I didn’t understand with an angle I didn’t understand, and got results to match :)
Using the new knowledge and git revert, I simply used the rotate function:
//movement - in EnemyController
movementDirection = new Vector3(0, 0, stepSize);
transform.Translate(movementDirection);
//rotation - in SpawnManager
GameObject enemy = gameManager.enemy2Pool.Get();
enemy.transform.Rotate(0, 180, 0);
and this worked perfectly.
And of course, it’s important to reset it before releasing the Enemy spaceship back into the pool, again with the help of gamedevbeginner:
private void ResetEnemy()
{
CancelInvoke();
movementCounter = 0;
//reset rotation
transform.eulerAngles = new Vector3(0, 90, 0);
}
And finally:
What challenges did you face rotating in unity? Or was it completely intuitive for you? Let me know in the comments :)