AI problem: Rotation

Hi.
I’m currently making a simple third person shooter and am almost finished with the AI. A final problem I have is however that the aiming stage doesn’t seem to work properly.

What’s supposed to happen is that the enemy starts out patroling the level, once he sees the player he engages. Engagement happens in four stages. First, the enemy moves into firing range, then it aims, then it fires a salvoe of rounds, then walks around while its attack cools down, then it goes back to the maneuver stage.

The enemy notices the player, enters aiming stage and… nothing. It turns a few degrees and then stops.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class EnemyAI : MonoBehaviour {
	public float health;
	float patrolpoint;
	public string mode;
	UnityEngine.AI.NavMeshAgent agent;
	float stoppingDistance;
	public Transform Target;
	public Transform PatrolPoint1;
	public string PP1;
	public Transform PatrolPoint2;
	public string PP2;
	public Transform PatrolPoint3;
	public string PP3;
	public Transform PatrolPoint4;
	public string PP4;
	public float maxRange;
	RaycastHit hit;
	public float PatrolSpeed;
	public float EngageSpeed;
	public float TurnSpeed;
	float DistanceToPlayer;
	public static bool firing;
	public float FireTime;
	float FireRemain;
	public float Cooldown;
	float CooldownLeft;
	string stage;
	Vector3 TargetDir;
	public Text DebugText;

	// Use this for initialization
	void Start () {
		agent = GetComponent<UnityEngine.AI.NavMeshAgent> ();
		patrolpoint = 1;
		FireRemain = FireTime;
		CooldownLeft = Cooldown;
		stage = "maneuvering";

	}

	// Update is called once per frame
//	void Update () {

//	}

	void Update () {
		DistanceToPlayer=Vector3.Distance(Target.position, transform.position);


		if (health < 0) {



		} 




		else {

			if (mode == "patrol") {

				agent.stoppingDistance = 0;
				agent.speed = PatrolSpeed;

				if (patrolpoint == 1) {
					agent.SetDestination (PatrolPoint1.position);

				}

				if (patrolpoint == 2) {
					agent.SetDestination (PatrolPoint2.position);

				}
				if (patrolpoint == 3) {
					agent.SetDestination (PatrolPoint3.position);

				}
				if (patrolpoint == 4) {
					agent.SetDestination (PatrolPoint4.position);

				} 
				else {

				}


				if(Vector3.Distance(transform.position, Target.position) < maxRange )
				{
					if(Physics.Raycast(transform.position, (Target.position - transform.position), out hit, maxRange))
					{
						if(hit.transform == Target)
						{
							mode = "engaged";

						}
					}
				}

			}

			if (mode == "engaged") {

				if (stage == "maneuvering") {
					agent.stoppingDistance = maxRange;
					agent.speed = EngageSpeed;
					agent.SetDestination (Target.position);
					firing = false;
					if (DistanceToPlayer <= maxRange) {
						if (Physics.Raycast (transform.position, (Target.position - transform.position), out hit, maxRange)) {
							if (hit.transform == Target) {
								stage = "aiming";
								FireRemain = FireTime;
								Vector3 TargetDir = Target.position - transform.position;

							} 
							else {
								agent.stoppingDistance = 1;
								agent.speed = EngageSpeed;
								agent.SetDestination (Target.position);
							}
						}
					}

					if (stage == "aiming") {
						float step = TurnSpeed * Time.deltaTime;

						Vector3 newDir = Vector3.RotateTowards (transform.forward, TargetDir, step, 0.0f);
						//Debug.DrawRay (transform.position, newDir, Color.red);

						// Move our position a step closer to the target.
					

						if (newDir == TargetDir) {
							stage = "firing";

						} 
						else {
							transform.rotation = Quaternion.LookRotation (newDir);

						}
					}

					if (stage == "firing") {
						firing = true;
						FireRemain = FireRemain - Time.deltaTime;
						if (FireRemain <= 0) {
							stage = "cooldown";
							CooldownLeft = Cooldown;
						}
					}


					if (stage == "cooldown") {
						firing = false;
						agent.stoppingDistance = maxRange;
						agent.speed = EngageSpeed;
						agent.SetDestination (Target.position);
						CooldownLeft = CooldownLeft - Time.deltaTime;

						if (CooldownLeft <= 0) {
							stage = "maneuvering";
						} 
						else {

						}
					}
				}
						

				}

			}
		DebugText.text = "Mode: " + mode.ToString() + "

Stage: " + stage.ToString() + "
Burst time: " + FireRemain.ToString()
+ "
Cooldown: " + CooldownLeft.ToString();

		}



	
	void OnTriggerEnter(Collider col)
	{
		//Check for a match with the specified name on any GameObject that collides with your GameObject
		if (col.gameObject.name == PP1) {
			patrolpoint = 2;
		}

		if (col.gameObject.name == PP2) {
			patrolpoint = 3;
		}

		if (col.gameObject.name == PP3) {
			patrolpoint = 4;
		}

		if (col.gameObject.name == PP3) {
			patrolpoint = 1;
		} 

		else {


		}

	}
}

in your code:

if (hit.transform == Target) {
                                 stage = "aiming";
                                 FireRemain = FireTime;
                                 Vector3 TargetDir = Target.position - transform.position;
 
                             } 

remove the “Vector3” from TargetDir in order to reference the instance in your class rather than a new local one.

if (hit.transform == Target) {
                                 stage = "aiming";
                                 FireRemain = FireTime;
                                 TargetDir = Target.position - transform.position;
 
                             }

OK, so I PARTIALLY figured out the issue on my own.
Turns out that my code rotated the enemy around the transform forward axis, while what I actually wanted was for it to use the transform up axis. Which is of course stupid, because I’ve locked the X and Z axis of the enemy transform so it won’t fall over.
This makes the enemy start swinging its gun towards the player, but for some reason it stops after rotating 90°. Can’t figure out this last bit…

The new code is:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class EnemyAI : MonoBehaviour {
	public float health;
	float patrolpoint;
	public string mode;
	UnityEngine.AI.NavMeshAgent agent;
	float stoppingDistance;
	public Transform Target;
	public Transform PatrolPoint1;
	public string PP1;
	public Transform PatrolPoint2;
	public string PP2;
	public Transform PatrolPoint3;
	public string PP3;
	public Transform PatrolPoint4;
	public string PP4;
	public float maxRange;
	RaycastHit hit;
	public float PatrolSpeed;
	public float EngageSpeed;
	public float TurnSpeed;
	float DistanceToPlayer;
	public static bool firing;
	public float FireTime;
	float FireRemain;
	public float Cooldown;
	float CooldownLeft;
	string stage;
	Vector3 TargetDir;
	public Text DebugText;
	Vector3 newDir;

	// Use this for initialization
	void Start () {
		agent = GetComponent<UnityEngine.AI.NavMeshAgent> ();
		patrolpoint = 1;
		FireRemain = FireTime;
		CooldownLeft = Cooldown;
		stage = "maneuvering";

	}

	// Update is called once per frame
//	void Update () {

//	}

	void Update () {
		DistanceToPlayer=Vector3.Distance(Target.position, transform.position);


		if (health < 0) {



		} 




		else {

			if (mode == "patrol") {

				agent.stoppingDistance = 0;
				agent.speed = PatrolSpeed;

				if (patrolpoint == 1) {
					agent.SetDestination (PatrolPoint1.position);

				}

				if (patrolpoint == 2) {
					agent.SetDestination (PatrolPoint2.position);

				}
				if (patrolpoint == 3) {
					agent.SetDestination (PatrolPoint3.position);

				}
				if (patrolpoint == 4) {
					agent.SetDestination (PatrolPoint4.position);

				} 
				else {

				}


				if(Vector3.Distance(transform.position, Target.position) < maxRange )
				{
					if(Physics.Raycast(transform.position, (Target.position - transform.position), out hit, maxRange))
					{
						if(hit.transform == Target)
						{
							mode = "engaged";

						}
					}
				}

			}

			if (mode == "engaged") {

				if (stage == "maneuvering") {
					agent.stoppingDistance = maxRange;
					agent.speed = EngageSpeed;
					agent.SetDestination (Target.position);
					firing = false;
					if (DistanceToPlayer <= maxRange) {
						if (Physics.Raycast (transform.position, (Target.position - transform.position), out hit, maxRange)) {
							if (hit.transform == Target) {
								stage = "aiming";
								FireRemain = FireTime;
								TargetDir = Target.position - transform.position;

							} 
							else {
								agent.stoppingDistance = 1;
								agent.speed = EngageSpeed;
								agent.SetDestination (Target.position);
							}
						}
					}

					if (stage == "aiming") {
						float step = TurnSpeed * Time.deltaTime;

						newDir = Vector3.RotateTowards (transform.up, TargetDir, step, 0.0f);
						//Debug.DrawRay (transform.position, newDir, Color.red);
						transform.rotation = Quaternion.LookRotation (newDir);
						// Move our position a step closer to the target.
					

						if (newDir == TargetDir) {
							stage = "firing";

						} 
						else {
							

						}
					}

					if (stage == "firing") {
						firing = true;
						FireRemain = FireRemain - Time.deltaTime;
						if (FireRemain <= 0) {
							stage = "cooldown";
							CooldownLeft = Cooldown;
						}
					}


					if (stage == "cooldown") {
						firing = false;
						agent.stoppingDistance = maxRange;
						agent.speed = EngageSpeed;
						agent.SetDestination (Target.position);
						CooldownLeft = CooldownLeft - Time.deltaTime;

						if (CooldownLeft <= 0) {
							stage = "maneuvering";
						} 
						else {

						}
					}
				}
						

				}

			}
		DebugText.text = "Mode: " + mode.ToString() + "

Stage: " + stage.ToString() + "
Burst time: " + FireRemain.ToString()
+ "
Cooldown: " + CooldownLeft.ToString() +"
Look Direction: " + newDir.ToString() + "
Enemy Direction: " + TargetDir.ToString();

		}



	
	void OnTriggerEnter(Collider col)
	{
		//Check for a match with the specified name on any GameObject that collides with your GameObject
		if (col.gameObject.name == PP1) {
			patrolpoint = 2;
		}

		if (col.gameObject.name == PP2) {
			patrolpoint = 3;
		}

		if (col.gameObject.name == PP3) {
			patrolpoint = 4;
		}

		if (col.gameObject.name == PP3) {
			patrolpoint = 1;
		} 

		else {


		}

	}
}