Hi hi,
I have a basic Enemy AI script for moving and firing using vector3 coordinates and bools. I’m trying to mangle coroutine sequences so they run in the right order and after a lot of consulting these forums (thanks all!)
I’ve managed to get the movement working in sequence (and the sequence does loop successfully), however the fire coroutine is not instantiating a new bullet after first initiation (the second one will just return nothing, etc). I’m thinking it’s because my sequence isn’t resetting the bool to make sure the bullet only fires once. Can’t for the life of me figure out why though!
Any help would be much appreciated. I’ve tried to annotate it where possible (as I am a C# newbie so I need to remind myself constantly!), so apologies if this code is a bit scrappy.
using UnityEngine;
using System.Collections;
public class EnemyAI001 : MonoBehaviour
{
//Me and you
public GameObject iEnemy;
public GameObject youPlayer;
//So I can face you
public Vector3 playernose;
//How fast I travel to my destination
public float approachSpeed;
//How fast I travel on my pre-scripted path after arriving from my origin
public float movementSpeed;
//My Gun
public GameObject weapon;
//My Bullet
public Rigidbody enemyBullet;
//Control the amount I shoot
public bool bulletAlive = false;
//Control how fast I shoot
public float bulletSpeed = 1f;
//Vectors for travel, and bools to dictate which sequence to run
//Origin Vector3 and Bools
Vector3 foclc = new Vector3(0, 0, 150);
bool originBool = true;
bool originBoolCapsule()
{
return originBool && !firstBool && !secondBool && !finalBool;
}
//Destination Vector3 and Bools
Vector3 x0y5z30 = new Vector3(0, 5, 30);
bool firstBool = false;
bool firstBoolCapsule()
{
return !originBool && firstBool && !secondBool && !finalBool;
}
//Second Destination Vector3 and Bools
Vector3 x20y10z15 = new Vector3(20, 10, 15);
bool secondBool = false;
bool secondBoolCapsule()
{
return !originBool && !firstBool && secondBool && !finalBool;
}
//Final Destination Vector3 and Bools
Vector3 xm20y0z45 = new Vector3(-20, 0, 45);
bool finalBool = false;
bool finalBoolCapsule()
{
return !originBool && !firstBool && !secondBool && finalBool;
}
// Assign my identity on Start
void Start ()
{
iEnemy = this.gameObject;
}
public void Update()
{
//Keep Looking at Player
playernose = new Vector3(youPlayer.transform.position.x, youPlayer.transform.position.y, youPlayer.transform.position.z);
iEnemy.transform.LookAt(playernose);
//If I've just spawned
if (originBoolCapsule())
{
StartCoroutine(OriginRunSquence());
}
//If I've reached my first destination, fire and move to my next one
else if (firstBoolCapsule())
{
StartCoroutine(RunSquence1());
}
//If I've reached my second destination, fire and move to my next one
else if (secondBoolCapsule())
{
StartCoroutine(RunSquence2());
}
//If I've reached my final destination, fire and loop back to the start
else if (finalBoolCapsule())
{
StartCoroutine(RunSquence3());
}
}
//Used for movement from spawn tofirst destination
public IEnumerator OriginRunSquence()
{
yield return StartCoroutine(moveToDestination());
}
//Used for sequencing first movement and firing and any other coroutines.
public IEnumerator RunSquence1()
{
yield return StartCoroutine(fire());
yield return new WaitForSeconds(1.0f);
yield return StartCoroutine(firstMove());
}
//Used for sequencing second movement and firing and any other coroutines.
public IEnumerator RunSquence2()
{
yield return StartCoroutine(fire());
yield return new WaitForSeconds(1.0f);
yield return StartCoroutine(secondMove());
}
//Used for sequencing final movement and firing and any other coroutines.
public IEnumerator RunSquence3()
{
yield return StartCoroutine(fire());
yield return new WaitForSeconds(1.0f);
yield return StartCoroutine(finalMove());
}
//Fire bool and fire coroutine
private void reloadBullet()
{
bulletAlive = false;
}
public IEnumerator fire()
{
if (bulletAlive == false)
{
//I'm loading up a bullet
Rigidbody newenemyBullet = Instantiate(enemyBullet, weapon.transform.position, weapon.transform.rotation) as Rigidbody;
//I'm firing a bullet
newenemyBullet.AddForce(iEnemy.transform.forward * bulletSpeed, ForceMode.VelocityChange);
bulletAlive = true;
yield return new WaitForSeconds(0.5f);
}
else if (bulletAlive == true)
{
yield break;
}
}
//Coroutine sequences
//Move to the destination from spawn
public IEnumerator moveToDestination()
{
if (iEnemy.transform.position != x0y5z30)
{
//Move me
iEnemy.transform.position = Vector3.Lerp(iEnemy.transform.position, x0y5z30, approachSpeed * Time.deltaTime);
yield return new WaitForSeconds(0.5f);
}
if (iEnemy.transform.position.z <= 30.5)
{
//Snap me
iEnemy.transform.position = x0y5z30;
yield return new WaitForSeconds(1);
originBool = false;
firstBool = true;
yield break;
}
}
//My first move after arriving at my destination
public IEnumerator firstMove()
{
if (iEnemy.transform.position != x20y10z15)
{
//Move me
iEnemy.transform.position = Vector3.Lerp(iEnemy.transform.position, x20y10z15, movementSpeed * Time.deltaTime);
yield return new WaitForSeconds(0.5f);
}
if (iEnemy.transform.position.z <= 15.2)
{
//Snap me
iEnemy.transform.position = x20y10z15;
yield return new WaitForSeconds(1);
originBool = false;
firstBool = false;
secondBool = true;
finalBool = false;
yield break;
}
}
//My second move
public IEnumerator secondMove()
{
if (iEnemy.transform.position != xm20y0z45)
{
//Move me
iEnemy.transform.position = Vector3.Lerp(iEnemy.transform.position, xm20y0z45, movementSpeed * Time.deltaTime);
yield return new WaitForSeconds(0.5f);
//Debug.Log("Working");
}
if (iEnemy.transform.position.z >= 44.8)
{
//Snap me
iEnemy.transform.position = xm20y0z45;
yield return new WaitForSeconds(1);
originBool = false;
firstBool = false;
secondBool = false;
finalBool = true;
yield break;
}
}
//The last scripted move in my behaviour pattern
public IEnumerator finalMove()
{
if (iEnemy.transform.position != x0y5z30)
{
//Move me
iEnemy.transform.position = Vector3.Lerp(iEnemy.transform.position, x0y5z30, movementSpeed * Time.deltaTime);
yield return new WaitForSeconds(0.5f);
}
if (iEnemy.transform.position.z <= 30.2)
{
//Snap me
iEnemy.transform.position = x0y5z30;
yield return new WaitForSeconds(1);
originBool = true;
firstBool = false;
secondBool = false;
finalBool = false;
yield break;
}
}
}