I’m not sure why, but Quaternion.Angle does not seem to be working in my game… Does it only work in 3D or something? I want my turret to rotate towards the enemy, and shoot towards the enemy. I had this working just fine before, but I wanted to make the turret rotate even when the gun was not reloaded and for some reason this broke everything lol.
So originally it was two coroutines, one waits for the other… It calls the first coroutine constantly if shooting is false, the end of the routine sets shooting to false. It rotates in the fixed update, the rotation is working fine. But it’s not waiting for the target… I have a while loop running, while Quaternion.angle is greater than 0.1f, but for some reason it’s shooting long before it even reaches the target. I tried printing off said angle, and it’s producing some strange results… Sometimes it seems proper, other times it prints of exactly 0 and other times 180?!
Anyway, here’s my coroutines
IEnumerator WaitForTarget()
{
if (nextTarget == null)
{
shooting = false;
yield break;
}
while (Mathf.Abs(Quaternion.Angle(transform.rotation, rotGoal))>0.01f || rateOfFire > 0)
{
if (nextTarget == null || AngleBetweenVector2(nextTarget.transform.position, transform.position) > angleToFire)
{
shooting = false;
yield break;
}
yield return null;
}
turning = false;
}
IEnumerator ShootBullet()
{
shooting = true;
nextTarget = CheckChangeTarget();
if (nextTarget == null || nextTarget.GetComponent<Zombie>().dead)
{
shooting = false;
yield break;
}
yield return WaitForTarget();
if (nextTarget == null || nextTarget.GetComponent<Zombie>().dead)
{
shooting = false;
yield break;
}
SoundManager.sm.PlaySound("Shot");
lightAnim.Play("MuzzleFlash", -1, 0);
shellEffect.Play();
GameObject b = Pool.pool.GetObject(bulletsPool, bullet);
b.GetComponent<Bullet>().SetVelocity(directionToEnemy);
b.transform.position = bulletSpawn.position;
b.SetActive(true);
shooting = false;
rateOfFire = rateOfFireSet;
nextTarget = null;
}
I know it’s kinda sloppy, i tried fixing everything up…So, what’s happening is it seems to be firing instantly when it acquires a target, so more likely than not, the while loop is just ending immediately… It doesn’t fire if there’s no target, however, it doesn’t wait until it’s rotated properly… If it’s relevant, here’s my rotation and target acquisition method as well,
private void FixedUpdate()
{
if (deactivated) return;
if (!baseTurret && !GameManager.gm.gameStarted) return;
if (nextTarget != null)
{
if (nextTarget.GetComponent<Zombie>().dead) nextTarget = CheckChangeTarget();
if (nextTarget != null)
{
float angle = Mathf.Atan2(directionToEnemy.y, directionToEnemy.x) * Mathf.Rad2Deg;
directionToEnemy = (nextTarget.position - transform.position).normalized;
angle = Mathf.Atan2(directionToEnemy.y, directionToEnemy.x) * Mathf.Rad2Deg;
rotGoal = Quaternion.AngleAxis(angle, Vector3.forward);
turretAxis.rotation = Quaternion.RotateTowards(turretAxis.rotation, rotGoal, rotationSpeed * Time.deltaTime);
if (transform.rotation != rotGoal)
{
if (nextTarget == null || AngleBetweenVector2(nextTarget.transform.position, transform.position) > angleToFire)
{
nextTarget = CheckChangeTarget();
if (nextTarget == null || nextTarget.GetComponent<Zombie>().dead)
{
shooting = false;
return;
}
}
}
else
{
nextTarget = CheckChangeTarget();
}
}
}
else
{
nextTarget = CheckChangeTarget();
}
}
Transform CheckChangeTarget()
{
Zombie[] zombies = FindObjectsOfType<Zombie>();
Zombie closestZombie = null;
float previousDistance = shootRange;
if (zombies.Length == 0) return null;
for (int i = 0; i < zombies.Length; i++)
{
float angle = AngleBetweenVector2(zombies[i].transform.position, transform.position);
if (angle > angleToFire) continue;
if (Vector2.Distance(zombies[i].transform.position, transform.position) < previousDistance && !zombies[i].dead)
{
previousDistance = Vector2.Distance(zombies[i].transform.position, transform.position);
closestZombie = zombies[i];
}
}
if (closestZombie != null)
{
return closestZombie.transform;
}
shooting = false;
StopAllCoroutines();
return null;
}
Can someone please help me figure out what I’m doing wrong? Previously I had it only calling the routine if the rate of fire was less than or equal to 0, but now I changed it to just call it when it’s shooting…
PS, 99% sure the Quaternion.Angle is not functioning as intended(or I just dont understand it lol) i just did a print in the while loop, it printed 180 4 times, and other times it didn’t even call it once…