- Home /
How can I rotate at a constant speed to look at a point?
Hi,
I have to rotate my unit to look at where I click my mouse.
I'm currently using a Quaternion.Slerp function to rotate my unit. However, it takes the same amount of time to rotate 90 degrees, as it does 180 degrees.
If it takes 2 seconds to rotate 180 degrees I only want it to take 1 second to rotate 90 degrees.
Do I have to create logic to change the speed at which I rotate, or is there a better function or something etc to do this?
Thanks for your help :)
You could do the progress divided by the answer you get from Quaternion.Angle(a, b)
, that would make them the same rate -> you may then need to times it all by a constant say 180 so that 180 degree rotation will stay at the speed it is now but 90 will be reached quicker.
Answer by Radivarig · Apr 21, 2014 at 09:42 AM
Try this:
Plane plane = new Plane(Vector3.up, 0);
float dist;
void Update () {
//cast ray from camera to plane (plane is at ground level, but infinite in space)
Ray ray = Camera.mainCamera.ScreenPointToRay(Input.mousePosition);
if (plane.Raycast(ray, out dist)) {
Vector3 point = ray.GetPoint(dist);
//find the vector pointing from our position to the target
Vector3 direction = (point - transform.position).normalized;
//create the rotation we need to be in to look at the target
Quaternion lookRotation = Quaternion.LookRotation(direction);
float angle = Quaternion.Angle(transform.rotation, lookRotation);
float timeToComplete = angle / rotationSpeed;
float donePercentage = Mathf.Min(1F, Time.deltaTime / timeToComplete);
//rotate towards a direction, but not immediately (rotate a little every frame)
//The 3rd parameter is a number between 0 and 1, where 0 is the start rotation and 1 is the end rotation
transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, donePercentage);
}
}
The idea is to calculate the rate of changing from 0 to 1 in the last argument of Slerp, since that is the percentage of desired transition, 0 is starting rotation and 1 is rotation we end up with.
from here.
Radivarig
Weird, I thought I replied to this.
Basically, this seems to be what I'm already doing.
Is there some part of your code which means that It will be faster to rotate 90 degrees than it is to rotate 180? I can't see it, I might be missing it.
If there is... I'm missing it, could you please expand?
Ok, I understand, I thought you wanted it to have the same rotation speed, but you want it to vary as well in different ratio, can you try:
//add this
float fixedAngle = 180f;
...
//replace line 17. with this
float donePercentage = $$anonymous$$athf.$$anonymous$$in(1f, (Time.deltaTime / timeToComplete) * (fixedAngle / angle);
...
Set your speed to get 2s for rotating 180 degrees, so if you have 90 degrees it will multiply it with 180f/90f so you get half time because it gets done twice as fast, 270 is 1.5 and same for every other ratio.
Awesome! Thanks so much :) That's a really good idea on how to do it! It works perfectly :)
Loving you right now :D
Answer by servival · Jun 27, 2015 at 04:01 PM
using UnityEngine;
using System.Collections;
public class AISmoothLookAT : MonoBehaviour {
public Transform target;
public Transform looker;
public Transform Xsmoothlooker;
public Transform Ysmoothlooker;
public float Xspeed = 2f;
public float Yspeed = 2f;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
looker.LookAt (target);
float YRotation = looker.eulerAngles.y;
float XRotation = looker.eulerAngles.x;
Xsmoothlooker.rotation = Quaternion.Slerp(Xsmoothlooker.rotation , Quaternion.Euler(0 , YRotation, 0), Time.deltaTime * Xspeed);
Ysmoothlooker.rotation = Quaternion.Slerp(Ysmoothlooker.rotation , Quaternion.Euler(XRotation , YRotation, 0), Time.deltaTime * Yspeed);
}
}