Reputation: 7714
My 2D object is looking up (transform.up = (0,1)
).
When I click somewhere in the screen, I want the object to look to where I clicked. I also want it to rotate linearly: it should rotate d
degrees per second, implying that it takes twice the time to rotate twice the angle.
Here is my code:
void Update() {
if (Input.GetMouseButtonDown(0)) {
Vector2 wPos = cameraRef.ScreenToWorldPoint(Input.mousePosition);
StartCoroutine(LookAt(mouseScreenPosition));
}
}
public IEnumerator LookAt(Vector2 position) {
Vector2 direction = (position - (Vector2) transform.position).normalized;
float angle = Vector2.SignedAngle(direction, transform.up);
float startAngle = transform.eulerAngles.z;
for(float t = 0; t <= 1; t += Time.deltaTime * (180 / Mathf.Max(1, Mathf.Abs(angle)))) {
transform.eulerAngles = new Vector3(0, 0, Mathf.Lerp(startAngle, startAngle - angle, t));
yield return null;
}
}
The factor I multiply Time.deltaTime
is 180 / Mathf.Max(1, Mathf.Abs(angle))
, which says that the bigger the angle, the bigger the time it takes to rotate, but I don't know if I'm doing it right (it works) or if this is the better way to do it.
Upvotes: 1
Views: 134
Reputation: 20259
Define some rotationSpeed
field:
public float rotationSpeed = 90f;
Use Quaternion.LookRotation
to get the Quaternion
you want to rotate towards. You want the local forward to point in the global forward direction and local up to point towards the target position, so use Quaternion.LookRotation(Vector3.forward,targetDirection)
:
public IEnumerator LookAt(Vector2 position) {
// casting to Vector2 and normalizing is redundant
Vector3 targetDirection = position - transform.position;
Quaternion targetRotation = Quaternion.LookRotation(Vector3.forward, targetDirection);
Then use Quaternion.RotateTowards
with the max amount of degrees you want to rotate in that frame until you are done rotating toward the goal rotation:
while (Quaternion.Angle(targetRotation, transform.rotation) > 0.01)
{
transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation,
time.deltaTime * rotationSpeed);
}
Altogether:
public float rotationSpeed = 90f;
public IEnumerator LookAt(Vector2 position) {
// casting to Vector2 and normalizing is redundant
Vector3 targetDirection = position - transform.position;
Quaternion targetRotation = Quaternion.LookRotation(Vector3.forward, targetDirection);
while (Quaternion.Angle(targetRotation, transform.rotation) > 0.01)
{
transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation,
time.deltaTime * rotationSpeed);
}
}
Upvotes: 1