Trouble with a State Machine for Turret
Hi!
So I want to preface this that I have not worked in Unity for very long and have minimal coding experience in general. A lot of the code that I have is a combination of stuff I have learned from school and on my own, and now I am at a loss.
Basically, I have created (what I think to be) a state machine for a turret AI. The idea is that the turret has 3 states: Idle, Fire, and Search. When the player enters the defined distance thresholds of the turret (they are public variables so the distance can be changed to fit whatever room it is in) and when the turrets vision is not blocked, the turret will fire at the player. When the player leaves either leaves the thresholds or is obscured from the turrets vision, the turret searches for the player (moves left and right for a few seconds) then snaps back to its original idle position. Below is the state machine trying to achieve this: void Update() { player_dist = Vector3.Distance(target.position, transform.position);
Vector3 targetDir = target.position - transform.position;
angleBetween = Vector3.Angle(transform.forward, targetDir);
bool wallBlocksVisibility = false;
RaycastHit hitInfo;
if (Physics.Raycast(transform.position, targetDir.normalized, out hitInfo, targetDir.magnitude))
Debug.Log("Working");
{
if(hitInfo.collider.gameObject != Player)
{
wallBlocksVisibility = true;
}
}
bool player_in_cone = player_dist <= player_dist_threshold && angleBetween >= -angleThreshold && angleBetween <= angleThreshold && !wallBlocksVisibility;
Debug.DrawRay(transform.position, targetDir.normalized * player_dist_threshold, Color.red);
Debug.DrawRay(transform.position, transform.forward * player_dist_threshold, Color.blue);
if(player_dist > player_dist_threshold && angleBetween < -angleThreshold || angleBetween > angleThreshold)
{
Debug.Log("player is not in range");
}
if(state == States.Idle && player_in_cone)
{
state = States.Fire;
Debug.Log("player in range");
}
else if(state == States.Fire && !player_in_cone)
{
state = States.Search;
FrameTimer = 6000;
MovingRight = true;
}
else if(state == States.Search && player_in_cone)
{
state = States.Fire;
Debug.Log("Target Reacquired");
}
else if(state == States.Search && !player_in_cone && FrameTimer <= abort)
{
state = States.Idle;
}
if(state == States.Idle)
{
gameObject.transform.position = startPosition;
gameObject.transform.rotation = startRotation;
Debug.Log("Turret is idle");
}
if (state == States.Fire)
{
transform.LookAt(target);
GameObject bullet = Instantiate(bulletPrefab, transform.position, transform.rotation);
Debug.Log("Turret is firing");
}
if(state == States.Search)
{
FrameTimer = FrameTimer - 1;
Debug.Log("Turret is searching");
if (MovingRight && currentRotation < angleThreshold)
{
transform.Rotate(Vector3.up, 0.01f, Space.Self);
currentRotation = currentRotation + 0.1f;
}
else if (MovingRight && currentRotation >= angleThreshold)
{
MovingRight = false;
}
else if (currentRotation > -angleThreshold)
{
transform.Rotate(Vector3.up, -0.01f, Space.Self);
currentRotation = currentRotation - 0.1f;
}
else
{
MovingRight = true;
if (FrameTimer <= abort)
{
gameObject.transform.position = startPosition;
gameObject.transform.rotation = startRotation;
}
}
}
}
The biggest problems the code is running into is:
When the player is within the cone, the turret does not continually fire single shots. It fires, goes into search for a moment, then back to firing again, and repeats this until I go out of range. I want it to instead continuously fire until the player leaves the range.
The turret does not listen to the angleThreshold i.e. once the player enters the cone, the turret tracks them (something I want to happen) but tracks them beyond the designated threshold (something I do not want to happen). Also, the turret tracks the player on the Y axis as well, something I do not want to happen (I plan on having the player jump over the shots as a way to dodge them). Also, as an aside, is there a way to draw the cone that I am creating? I have in the code a way to draw the range of the cone, but not the cone itself.
When the turret fires, it fires like, 5-11 shots all at once, all on top of each other. I'm unsure why this is happening.
I can't seem to find any other issues, and I hope this wasn't too many questions in one post. This is my first time posting so a preemptive thanks for all the help!