Need to resurrect this, as I thought that I had things working correctly, but it appears not.
The problem is simple - What I’d like is to have the projectile rotate in the direction of the player. So, if the projectile was moving straight up, and the player was to the left of the projectile, it would rotate to the left towards the player. If the player was to the right of the projectile… well, you get the idea.
Right now, If the projectile starts off moving to the left, it will stop dead in its tracks and immediately start moving/turning to the right towards the player. If the projectile starts off moving to the right, it will sort of work, but looks a bit jarring.
Based on the project given in Kurt’s post, I am using this code.
if (target != null)
{
Vector3 delta = target.transform.position - transform.position;
float headingToTarget = Mathf.Atan2(delta.y, delta.x) * Mathf.Rad2Deg;
float angleError = Mathf.DeltaAngle(headingToTarget, currentHeading);
if (Mathf.Abs(angleError) > 2.0f)//Mathf.Abs
{
currentHeading = Mathf.MoveTowardsAngle(currentHeading, headingToTarget, (rotationSpeed) * Time.deltaTime);
}
transform.rotation = Quaternion.Euler(0, 0, currentHeading);
transform.position += transform.right * moveSpeed * Time.deltaTime;
}
I’m not sure what I’m doing wrong here, except messing with transforms directly, but in the examples, at least from what I can tell, it’s doing the same thing? I must be missing something there.
EDIT: OK, so I have fixed this issue by making a couple of changes to the code above. First, I change the line
currentHeading = Mathf.MoveTowardsAngle(currentHeading, headingToTarget, (rotationSpeed) * Time.deltaTime);
into this
currentHeading += (rotationSpeed * Time.deltaTime);
currentHeading %= 360;
//or
currentHeading -= (rotationSpeed * Time.deltaTime);
currentHeading %= 360;
I use either one based on which direction the projectile was moving when it started flying. Then, I can switch back to the previous code if the projectile rotates past the player. I can determine if the projectile rotates past the player by using a Raycast2D, and checking for the player layer. If it finds the player, I switch back to use the other code. A simple bool should suffice there. This way, the projectile can once again rotate towards the player.
There might be a better way to handle this, or even a much simpler way, but this is what I came up with, with the help of a friend of mine.