I'm making a 3D space shooter in Unity (think Star Fox). The ship, when I move it around the map, should rotate slightly (smoothly) in the direction I'm controlling it.
I have smoothness mostly working. When I press an arrow key, the ship banks in that direction, and when I release it, it smoothly returns to the default rotation.
However, if I quickly change the direction it's rotating before it has the chance to get back to the default rotation, instead of rotating from "banking left" to "banking right", for example, it instantly snaps to the default rotation before beginning the smooth rotation.
Here's what it looks like:
In addition, when I connect a joystick (instead of using arrow keys) to control the ship, I get a different problem: The ship has literally no smoothing at all, rotating one-to-one with the direction the joystick is rotated in. Here's what that looks like:
Here's the code that controls ship movement:
public bool inverted = true;
public float speed = 20; //speed modifier of horizontal/vertical movement
public float rotSpeed = 120; //speed modifer of rotation (ship tilting)
public float ZRotMax = 30f;
public float YRotMax = 50f;
public float XRotMax = 30f;
public float width = 30;
public float height = 15;
public float centerDriftStrength = 5; //lower is stronger, higher is weaker.
// Update is called once per frame
void Update () {
//Get input
float controlHorizontal = Input.GetAxis("Horizontal");
float controlVertical = (inverted ? -Input.GetAxis("Vertical") :
Input.GetAxis("Vertical"));
//Add mild center drift
float moveHorizontal = controlHorizontal - ((transform.position.x)
/ (width * centerDriftStrength));
float moveVertical = controlVertical - ((transform.position.y)
/ (height * centerDriftStrength));
//Modify position
transform.position += (new Vector3(moveHorizontal, moveVertical, 0)
* speed * Time.deltaTime);
//Cosmetic rotation based on controller input
Quaternion oldRot = Quaternion.identity;
Quaternion newRot = Quaternion.Euler(XRotMax * -controlVertical,
YRotMax * controlHorizontal, ZRotMax * -controlHorizontal);
transform.rotation = Quaternion.Slerp(oldRot, newRot,
Time.deltaTime * rotSpeed);
}
In particular:
transform.rotation = Quaternion.Slerp(oldRot, newRot, Time.deltaTime * rotSpeed);
Seems to be what I need to look at.
rotSpeed should cap the speed of rotation on the ship, so that it can't instantly rotate in a different direction. Right now, when rotSpeed is less than 120 or so, the ship twitches while rotating, and if it's particularly low, like 10, the ship barely rotates at all.
(The rotSpeed variable doesn't seem to be working anyways -- setting it to 30000 or something doesn't make the rotation any faster.)
Basically, I want the ship to always rotate smoothly, never jumping instantly from one rotation to the next. I'm not sure if I need to use Slerp for this, or if there's some better smoothing method available to Unity.
Thanks, and if anybody knows of other ways to smooth rotation between constantly-changing Vector3s/Quaternions, please tell me!