The hazards in my unity game are not spawning - c#

I have a game in which you are a player cube and you have to dodge other cubes as they come through your way. The enemy cubes should spawn because of a script I have called GameController. But the cubes are not spawning. Please Help. (Also whenever my cube gets destroyed the gameover and the restart functions are not working)
I tried Recreating the prefab and the code, but nothing happened. Also, the same code is working in my other games
Here is my code:
void Start()
{
gameOver = false;
restart = false;
restartText.text = "";
gameOverText.text = "";
score = 0;
UpdateScore();
StartCoroutine(SpawnWaves());
}
void Update()
{
if (restart)
{
if (Input.GetKeyDown(KeyCode.R))
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
}
}
}
IEnumerator SpawnWaves()
{
yield return new WaitForSeconds(startWait);
while (true)
{
for (int i = 0; i < hazardCount; i++)
{
GameObject hazard = hazards[Random.Range(0, hazards.Length)];
Vector3 spawnPosition = new Vector3(Random.Range(-spawnValues.x, spawnValues.x), spawnValues.y, spawnValues.z);
Quaternion spawnRotation = Quaternion.identity;
GameObject newSpawn = Instantiate(hazard, spawnPosition, spawnRotation) as GameObject;
yield return new WaitForSeconds(spawnWait);
}
yield return new WaitForSeconds(waveWait);
if (gameOver)
{
restartText.text = "Press 'R' for Restart";
restart = true;
break;
}
}
}
public void AddScore(int newScoreValue)
{
score += newScoreValue;
UpdateScore();
}
void UpdateScore()
{
scoreText.text = "Score: " + score;
}
public void GameOver()
{
gameOverText.text = "Game Over!";
gameOver = true;
}
}
I expect the enemies to spawn but they are not

I have copy and pasted your example code into an example project. In this example your script works as expected, as you already mentioned that it works in other projects.
So in my opinion it has something to do with the inspector values.
Check the following:
Did you checked that your hazardCount is greater than zero?
Is your hazardArray completely filled with prefabs?
(If not that should cause the not-spawning but should also cause a null-reference-exception.)
Another option is that you make a screenshot or provide your values in the inspector somehow, so its possible to reproduce the error.
Offtopic: Your Restart after the gameOver is delayed, because the if(gameOver)-Clause comes after the WaitForSeconds(waveWait). My suggestion is to change it to the following:
public GameObject[] hazards;
public Vector3 spawnValues;
public int hazardCount;
public float spawnWait;
public float startWait;
public float waveWait;
public Text scoreText;
public Text restartText;
public Text gameOverText;
private bool gameOver;
private bool restart;
private int score;
private Coroutine gameRoutine;
void Start()
{
gameOver = false;
restart = false;
restartText.text = "";
gameOverText.text = "";
score = 0;
UpdateScore();
gameRoutine = StartCoroutine(SpawnWaves());
}
void Update()
{
if (restart)
{
if (Input.GetKeyDown(KeyCode.R))
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
}
}
}
IEnumerator SpawnWaves()
{
yield return new WaitForSeconds(startWait);
while (true)
{
for (int i = 0; i < hazardCount; i++)
{
GameObject hazard = hazards[Random.Range(0, hazards.Length)];
Vector3 spawnPosition = new Vector3(Random.Range(-spawnValues.x, spawnValues.x), spawnValues.y, spawnValues.z);
Quaternion spawnRotation = Quaternion.identity;
GameObject newSpawn = Instantiate(hazard, spawnPosition, spawnRotation) as GameObject;
yield return new WaitForSeconds(spawnWait);
}
yield return new WaitForSeconds(waveWait);
}
}
public void AddScore(int newScoreValue)
{
score += newScoreValue;
UpdateScore();
}
void UpdateScore()
{
scoreText.text = "Score: " + score;
}
public void GameOver()
{
gameOverText.text = "Game Over!";
restartText.text = "Press 'R' for Restart";
restart = true;
gameOver = true;
StopCoroutine(gameRoutine);
}
What i have changed here is, that the if-condition is removed and the Coroutine is now stored at Start() and is directly stop as the gameOver() method gets executed. Another option instead of the StopCoroutine() would be to set the condition of your while-loop to while(!gameOver).

Related

How do I write the code to deduct one hit point?

Working on a Basketball Shooter on a unit. I am doing the part that is responsible for subtracting the cells of life. The part of the code that is responsible for adding points is triggered when you touch the "Bonus" component and adds points, but the next part of the code that is responsible for reducing health does not work. By design, this should happen after the ball does not hit the "Bonus" object and comes into contact with the "Terraine" object. How to write a code so that if there is no touch with the "Bonus" object and then there is a touch with the "Terraine" object, one life point is subtracted?
public GameObject hp3;
public GameObject hp2;
public GameObject hp1;
int score = 0;
int best = 0;
void Awake()
{
rb = GetComponent<Rigidbody>();
col = GetComponent<Collider>();
//instance = this;
}
private void Start()
{
best = PlayerPrefs.GetInt("best", 0);
scoreText.text = "Score: " + score.ToString();
bestScoreText.text = "Best: " + best.ToString();
}
public void Push(Vector2 force)
{
rb.AddForce(force, ForceMode.Impulse);
}
public void ActivateRb()
{
rb.isKinematic = false;
}
public void DesactivateRb()
{
rb.velocity = Vector3.zero;
//rb.angularVelocity = 0f;
rb.isKinematic = true;
}
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.name == "Terraine")
{
transform.position = new Vector3(Random.Range(-4f, 8f), Random.Range(2f, 7f), -0.2f);
DesactivateRb();
}
}
public void OnTriggerExit(Collider other)
{
if (other.gameObject.name == "Bonus")
{
score += 2;
scoreText.text = "Score: " + score.ToString();
if (best < score)
PlayerPrefs.SetInt("best", score);
}
if (other.gameObject.name != "Bonus")
{
health = health - 1;
}
}
void Update()
{
if (health == 3)
{
hp3.SetActive(true);
hp2.SetActive(false);
hp1.SetActive(false);
}
if (health == 2)
{
hp3.SetActive(false);
hp2.SetActive(true);
hp1.SetActive(false);
}
if (health == 1)
{
hp3.SetActive(false);
hp2.SetActive(false);
hp1.SetActive(true);
}
}
Don't know c#, but would something as simple as this work?
Hard to know without the logic.
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.name == "Terraine")
{
transform.position = new Vector3(Random.Range(-4f, 8f), Random.Range(2f, 7f), -0.2f);
DesactivateRb();
if (flag != 1)
{
health = health - 1;
}
else
{
flag = 0; //reset flag if 1
}
}
}
public void OnTriggerExit(Collider other)
{
if (other.gameObject.name == "Bonus")
{
score += 2;
flag = 1;
scoreText.text = "Score: " + score.ToString();
if (best < score)
PlayerPrefs.SetInt("best", score);
}
}

Object is instantiated at wrong position and every time in the same place

I'm puzzled, no idea how this is happening... I don't know how my prefab always spawns at the same place even tho I made it set position to the spawner every time. I will put my code from the Spawn script, but I think that can be something in the scene... any ideas? Tell me if you need more info about my scripts etc.
public GameObject prefab, prefab2, prefab3;
public float respawn = 1f;
public float respawn2 = .2f;
public float respawn3 = 50f;
private float rounds = 1f;
// Start is called before the first frame update
void Start()
{
spawne();
StartCoroutine(invader());
StartCoroutine(star());
StartCoroutine(powerup());
}
private void spawne()
{
GameObject a = Instantiate(prefab) as GameObject;
a.transform.position = new Vector2(transform.position.x, transform.position.y);
}
private void spawne2()
{
GameObject b = Instantiate(prefab2) as GameObject;
b.transform.position = new Vector2(transform.position.x, transform.position.y);
}
private void spawne3()
{
GameObject c = Instantiate(prefab3) as GameObject;
c.transform.position = new Vector2(transform.position.x, transform.position.y);
c.transform.position = transform.position;
c.transform.rotation = transform.rotation;
}
IEnumerator powerup()
{
while (true)
{
yield return new WaitForSeconds(respawn3);
spawne3();
if (respawn3 > 5f)
{
rounds += 0.2f;
respawn3 -= 2f * rounds;
}
else if (respawn3 < 5f)
{
respawn3 = 15f;
}
}
}
IEnumerator star()
{
while (true)
{
yield return new WaitForSeconds(respawn2);
spawne2();
}
}
IEnumerator invader()
{
while (true)
{
yield return new WaitForSeconds(respawn);
spawne();
}
}

Trying to make a reload delay in c# yet running into a bug

So I have been trying to make a game recently and I have ran into a unexpected bug.
As I run the script I have wrote I can shoot 10 bullets out of my gun, then it plays a reload sound and waits two seconds using coroutines and it adds 1200 to my clip for no reason? So I added the if statement telling it that if the clip size goes over 10 then revert it to 10 but now it goes to 19 for a few seconds then back to 10.
I am unaware if I am being a idiot or something but would be glad for some help, also sorry if this is a duplicate but i was unable to find anything similar in c#.
EDIT: i have fixed the bug now, thanks for the help, ill share the new code after the old code for future reference!
My old code:
{
public float fireRate = 10;
public float damage = 15;
public int clipsize;
float timeUntilFire = 0;
public float ReloadSpeed = 2.5f;
float reloadtime;
public Transform firePoint;
public GameObject bullet;
public AudioSource gunshotaudio;
public AudioSource ReloadSound;
void Awake()
{
gunshotaudio = GetComponent<AudioSource>();
clipsize = 10;
}
// Update is called once per frame
void Update()
{
// if the button pressed is fire 1 and
if (Input.GetButtonDown("Fire1") && clipsize != 0)
{
timeUntilFire = Time.time / fireRate;
gunshotaudio.Play();
Shoot();
clipsize -= 1;
Debug.Log(clipsize);
}
if(clipsize <= 0)
{
ReloadSound.Play();
StartCoroutine(Wait());
StopCoroutine(Wait());
}
if(clipsize >= 11)
{
clipsize = 10;
}
}
IEnumerator Wait()
{
yield return new WaitForSecondsRealtime(2);
clipsize += 10;
}
void Shoot()
{
gunshotaudio.Play();
Instantiate(bullet, firePoint.position,firePoint.rotation);
}
}
** My New Code: **
{
public float fireRate = 10;
public float damage = 15;
public int clipsize;
float timeUntilFire = 0;
public float ReloadSpeed = 2.5f;
float reloadtime;
bool CanShoot;
bool IsReloading;
bool reloading;
public Transform firePoint;
public GameObject bullet;
public AudioSource gunshotaudio;
public AudioSource ReloadSound;
void Awake()
{
gunshotaudio = GetComponent<AudioSource>();
clipsize = 10;
}
void Start()
{
if (clipsize > 0)
{
CanShoot = true;
}
}
// Update is called once per frame
void Update()
{
// if the button pressed is fire 1 and
if (Input.GetButtonDown("Fire1") && clipsize != 0)
{
timeUntilFire = Time.time + fireRate;
gunshotaudio.Play();
Shoot();
clipsize--;
Debug.Log(clipsize);
}
// reloading
if(Input.GetKeyDown(KeyCode.R))
{
IsReloading = true;
ReloadSound.Play();
}
if (IsReloading)
{
StartCoroutine(Wait());
}
}
IEnumerator Wait()
{
if(reloading == false)
{
if (IsReloading)
{
reloading = true;
CanShoot = false;
yield return new WaitForSeconds(1);
clipsize = 10;
IsReloading = false;
Debug.Log(clipsize);
CanShoot = true;
reloading = false;
}
else
{
}
}
}
void Shoot()
{
gunshotaudio.Play();
Instantiate(bullet, firePoint.position,firePoint.rotation);
}
}
You aren't checking to see if a reload is already in process, so you are queuing up a bunch of reload events which all add +10 to the clip resulting in extras.
Add a reloading bool and check that before you initiate your coroutine and instead of adding 10 to the clip, set the clip to 10.

Unity Coroutine for gameMenu

I'm building a game like the roll a ball game on the tutorials in the Unity website, now I'm focused on the gameover menu, when the player lose all his lives I activate the gameover text, the yes and no text and the rawImage that is displayed behind the yes text by default, the thing is I want the image that is behind the yes text to go down to no and up to yes with the arrow keys. I think I implemented it right with the keys, but I feel like I need a coroutine to build this, because it just leaves the gameover function, without waiting the user input, so after this how can I build this in a right mode?
I did this at the moment:
public class Manager : MonoBehaviour {
private float checkPoint = 0;
public GameObject Ball;
private GameObject cam;
private Object newBall;
public int lifes;
public Text Lifetext;
private bool gameIsOver = false;
private Text gameOver;
private Text playAgain;
private Text yes;
private Text no;
private RawImage TopMenuBall;
void Awake(){
Lifetext = GameObject.Find("Lifes").GetComponent<Text>();
gameOver = GameObject.Find("GameOver").GetComponent<Text>();
playAgain = GameObject.Find("PlayAgain").GetComponent<Text>();
yes = GameObject.Find("Yes").GetComponent<Text>();
no = GameObject.Find("No").GetComponent<Text>();
TopMenuBall = GameObject.Find("TopMenuBall").GetComponent<RawImage>();
gameOver.enabled = false;
playAgain.enabled = false;
yes.enabled = false;
no.enabled = false;
TopMenuBall.enabled = false;
TopMenuBall.transform.localPosition = new Vector3(-68,-41,0);
}
void Start(){
lifes = 3;
Lifetext.text = " x" + lifes;
SpawnBall ();
cam = GameObject.Find ("Main Camera");
}
public void LifeUp(){
lifes++;
Lifetext.text = "X " + lifes;
}
public void LifeDown(){
if (lifes <= 0) {
GameOver ();
} else {
lifes--;
Lifetext.text = "X " + lifes;
}
}
public void GameOver(){
Debug.Log ("gameover");
gameOver.enabled = true;
playAgain.enabled = true;
yes.enabled = true;
no.enabled = true;
TopMenuBall.enabled = true;
if (Input.GetKeyDown (KeyCode.DownArrow)) {
TopMenuBall.transform.localPosition = new Vector3 (-68, -82, 0);
Debug.Log ("up");
}
else if (Input.GetKeyDown(KeyCode.UpArrow))
TopMenuBall.transform.localPosition = new Vector3(-68,-41,0);
}
void SpawnBall(){
Vector3 spawnPosition = new Vector3 (0.02f,1.4f,-39f);
Quaternion spawnRotation = Quaternion.identity;
newBall = Instantiate (Ball, spawnPosition, spawnRotation);
Camera.main.GetComponent<cameraMove>().player = (GameObject)newBall;
}
when the user lose all the lifes it enters the gameover function and there is the problem, how can I solve this?
You should use Update() method to get the user inputs. Because you need it to be constantly checked and the Update method exists exactly for this kind of situation, once it is called every frame.
So, your code should look like this:
void Update() {
if (TopMenuBall.enabled) {
if (Input.GetKeyDown (KeyCode.DownArrow)) {
TopMenuBall.transform.localPosition = new Vector3 (-68, -82, 0);
Debug.Log ("up");
}
else if (Input.GetKeyDown(KeyCode.UpArrow))
TopMenuBall.transform.localPosition = new Vector3(-68,-41,0);
}
}

Only one gameobject being affected by script

Making a state machine AI "game" I have 3 states Movement, Combat, and View. They all work very well, now I'm making a flee (by the way if anyone has any good links to tutorials or info that they have off hand I would love that) state so I want to make all three previous state in their Idle mode. Which works perfectly when I have 1 AI. As soon as I put the rest (there is 6 total now) it will still only affect 1, but then after some time it will "release" I guess it the best term the script and just goes back to the three states that are supposed to be idle. I think that in my Coin script I am saying find and I think it needs to be something else, I'm just not sure if that's even right but based off of my previous experiences that's usually the case with Unity. I'll post some code, but here's some info that may help your eyes by not having to read through everything:
-I have a bool set up in my AIClass that is false until one of my gameobjects collides with a 'coin', and coin is jsut a gameobject i put in my game to test out my AI behaviors. When that bool is true, in my update in my AIClass(sorry it's at the very bottom of the script you can scroll down, but I had to put other code just in case I was doing something in that to cause my problem.) It sets the state of MovementState to Idle, CombatState to Idle and ViewState to Idle.
-Also, when that bool is false is the only time that the call for the transition of states occur. For example, normally the AI will search around trying to find player, if they find him they go near him, and if they are in a certain distance they fire. Pretty simple. The movement between those states happens at the end of each IENumerator when the 'NextMovementState()' or 'NextCombatState()' or 'NextViewState()' are called. So when the bool is true those should never be called, halting the AI from moving to another state other than Idle (to what it's set at when the bool is true in the update).
And this works fine when I have only 1 AI in the game.
CoinScript.cs
using UnityEngine;
using System.Collections;
public class CoinScript : MonoBehaviour {
private AIClass a;
// Use this for initialization
void Start () {
a = GameObject.Find ("Enemy").GetComponent<AIClass>();
}
// Update is called once per frame
void Update () {
}
void OnCollisionEnter(Collision collision)
{
if (collision.collider)
{
if(collision.gameObject.tag == "Enemy" || collision.gameObject.tag == "EnemyProjectile")
{
Physics.IgnoreCollision(rigidbody.collider,collision.collider);
//Debug.Log ("Enemy");
}
if(collision.gameObject.tag == "Player")
{
Debug.Log ("triggered!");
a.fleeBool = true;
Destroy(gameObject);
}
}
}
}
AIClass.cs
using UnityEngine;
using System.Collections;
public class AIClass : MonoBehaviour
{
public NavMeshAgent agent;
//Ammo in gun before reloading is required
public int ammo = 30;
public int maxAmmo = 30;
//Number of bullets a gun fires in sequence on 1 trigger pull
public int chamber = 3;
public int maxChamber = 3;
//Pause between bursts or mouse presses, set to 0 for fully automatic
public double chamberTime = 120;
//How fast a gun fires in RPS
public int fireRate = 7;
public int fireTimer = 0;
//How fast a gun can reload
public int reloadTime = 3;
public int reloadTimer = 0;
//Number of bullets fired per shot
public int bulletsFired = 1;
public GameObject bulletClone;
//Acceptable degrees as to which the AI will begin firing at its target
public int firingAngle = 5;
//Vision cone of degrees to left and right
public int visionAngle = 35;
public int visionDistance = 100;
public int vRotationSpeed = 3;
public int vIdleTimer = 0;
public int vIdleTime = 300;
public int searchTimer = 0;
public int searchTime = 300;
public int mIdleTimer = 0;
public int mIdleTime = 300;
public bool isFocusedOnPlayer = false;
public bool seesPlayer = false;
//
public bool fleeBool;
public bool flee;
public enum MovementState
{
MSearch,
MMoving,
MIdle,
}
public enum CombatState
{
CFiring,
CReloading,
CIdle,
}
public enum ViewState
{
VSearch,
VFocus,
VIdle,
}
public enum FleeState
{
FSearch,
FMoving,
FIdle
}
public CombatState combatState;
public ViewState viewState;
public MovementState movementState;
public FleeState fleeState;
//Search state (knows where player is and will head to the player's location)
IEnumerator MSearchState ()
{
mIdleTimer = 0;
int stuckTimer = 0;
while (movementState == MovementState.MSearch)
{
//I've arrived at my location, if idle too long, then go back to idle state
if(Vector3.Distance(transform.position,agent.destination) < 3)
mIdleTimer++;
//I'm stuck and haven't moved in a while, go back to idle state
if(agent.velocity.magnitude < 1)
stuckTimer++;
if(seesPlayer || mIdleTimer > mIdleTime + 200 || stuckTimer > 300)
{
agent.destination = transform.position;
movementState = MovementState.MIdle;
}
yield return 0;
}
if (!flee) {
NextMovementState();
}
}
//Wander state
IEnumerator MMovingState ()
{
while (movementState == MovementState.MMoving)
{
//Wander code... Create a random angle and convert it to radians
float randomAngle = (float)(3.14/180)*Random.Range(0,360);
//Normalize direction vector, as we will be using it to calculate where we place the circle
Vector3 tempV = agent.velocity;
Vector3.Normalize (tempV);
//Using our relative position, 5 units in front of us. Use the generated angle to find the point on the circle that we want to go to
agent.destination = transform.position + tempV * 3 + new Vector3(Mathf.Cos (randomAngle)*3,0,Mathf.Sin (randomAngle)*3);
//Check to see if we are within the arena bounds, if not, push our projected vector back inside
if(agent.destination.x > 24)
agent.destination = agent.destination + new Vector3(-7,0,0);
if(agent.destination.x < -24)
agent.destination = agent.destination + new Vector3(7,0,0);
if(agent.destination.z > 24)
agent.destination = agent.destination + new Vector3(0,0,-7);
if(agent.destination.z < -24)
agent.destination = agent.destination + new Vector3(0,0,7);
if(seesPlayer)
{
agent.destination = transform.position;
movementState = MovementState.MIdle;
}
yield return 0;
}
if (!flee) {
NextMovementState ();
}
}
//Not moving, if I don't see the player for awhile, then go wander
IEnumerator MIdleState ()
{
mIdleTimer = 0;
while (movementState == MovementState.MIdle)
{
if(seesPlayer)
mIdleTimer = 0;
else
mIdleTimer++;
if(mIdleTimer > mIdleTime + Random.Range (-100,100))
movementState = MovementState.MMoving;
yield return 0;
}
if (!flee) {
NextMovementState ();
}
}
//Visual search state, randomly look around and check to see if we see the player
IEnumerator VSearchState ()
{
Transform target = GameObject.FindWithTag ("Player").transform;
Vector3 targetPosition = target.position;
while (viewState == ViewState.VSearch)
{
searchTimer--;
//Vision Cone calculation
Vector3 targetDir = target.position - transform.position;
Vector3 forward = transform.forward;
float angle = Vector3.Angle(targetDir, forward);
//If player is within vision cone then proceed
if (angle < visionAngle)
{
//Check to see if there are any object between player and myself
RaycastHit hit;
if (Physics.Raycast(transform.position, targetDir, out hit))
{
if(hit.transform == target)
{
seesPlayer = true;
viewState = ViewState.VFocus;
}
}
}
//Look in another direction
if(searchTimer < 0)
{
searchTimer = searchTime + Random.Range (-100,100);
targetPosition = new Vector3(Random.Range (-100,100),transform.position.y,Random.Range (-100,100));
}
transform.rotation = Quaternion.Slerp(transform.rotation,Quaternion.LookRotation(targetPosition - transform.position), vRotationSpeed*Time.deltaTime);
yield return 0;
}
if (!flee) {
NextViewState ();
}
}
//Focus on player
IEnumerator VFocusState ()
{
Transform target = GameObject.FindWithTag ("Player").transform;
while (viewState == ViewState.VFocus)
{
//Vision Cone calculation
Vector3 targetDir = target.position - transform.position;
Vector3 forward = transform.forward;
float angle = Vector3.Angle(targetDir, forward);
if (angle > visionAngle)
viewState = ViewState.VIdle;
else
{
RaycastHit hit;
//Check if there are any objects in the way
if (Physics.Raycast(transform.position, targetDir, out hit))
{
if(hit.transform == target)
{
//Tell other AI where player is
GameObject[] objArray = GameObject.FindGameObjectsWithTag ("Enemy");
AIClass[] enemyArray = new AIClass[objArray.Length];
for(int i = 0; i < enemyArray.Length; i++)
{
enemyArray[i] = (AIClass)objArray[i].GetComponent(typeof(AIClass));
if(i >= enemyArray.Length/2)
enemyArray[i].agent.destination = target.position;
else
enemyArray[i].agent.destination = target.position + target.forward*5;
enemyArray[i].movementState = MovementState.MSearch;
}
seesPlayer = true;
transform.rotation = Quaternion.Slerp(transform.rotation,Quaternion.LookRotation(target.position - transform.position), vRotationSpeed*Time.deltaTime);
//Check to see player is within sights of the gun
if (angle < firingAngle)
isFocusedOnPlayer = true;
else
isFocusedOnPlayer = false;
}
else
{
//I no longer see the player
seesPlayer = false;
viewState = ViewState.VIdle;
isFocusedOnPlayer = false;
}
}
}
yield return 0;
}
if (!flee) {
NextViewState ();
}
}
//Visual idle state, basically the ai is just looking forward
IEnumerator VIdleState ()
{
vIdleTimer = 0;
Transform target = GameObject.FindWithTag ("Player").transform;
while (viewState == ViewState.VIdle)
{
//Vision cone calculation
vIdleTimer++;
Vector3 targetDir = target.position - transform.position;
Vector3 forward = transform.forward;
float angle = Vector3.Angle(targetDir, forward);
//Check to see if there is an object is between the ai and the player
if (angle < visionAngle)
{
RaycastHit hit;
if (Physics.Raycast(transform.position, targetDir, out hit))
{
if(hit.transform == target)
{
seesPlayer = true;
viewState = ViewState.VFocus;
}
}
}
if(vIdleTimer > vIdleTime)
viewState = ViewState.VSearch;
yield return 0;
}
if (!flee) {
NextViewState ();
}
}
//Firing gun state
IEnumerator CFiringState ()
{
while (combatState == CombatState.CFiring)
{
if(!isFocusedOnPlayer)
combatState = CombatState.CIdle;
fireTimer--;
if(ammo > 0)
{
if(chamber > 0)
{
if(fireTimer <= 0)
{
for(int i = 0; i < bulletsFired;i++)
{
GameObject temp = (GameObject) Instantiate (bulletClone,transform.position + transform.forward,transform.rotation);
temp.rigidbody.AddForce(transform.forward*500);
}
fireTimer = 60 / fireRate;
ammo--;
chamber--;
}
}
else
{
chamber = maxChamber;
fireTimer = (int)(60/chamberTime);
}
}
else
{
combatState = CombatState.CReloading;
}
yield return 0;
}
if (!flee) {
NextCombatState ();
}
}
IEnumerator CReloadingState ()
{
reloadTimer = reloadTime * 60;
while (combatState == CombatState.CReloading)
{
reloadTimer--;
if(reloadTimer <= 0)
{
ammo = maxAmmo;
combatState = CombatState.CIdle;
}
yield return 0;
}
if (!flee) {
NextCombatState ();
}
}
IEnumerator CIdleState ()
{
while (combatState == CombatState.CIdle)
{
if(isFocusedOnPlayer)
combatState = CombatState.CFiring;
yield return 0;
}
if (!flee) {
NextCombatState ();
}
}
void Start ()
{
fleeBool = false;
flee = false;
NextCombatState();
NextViewState();
NextMovementState();
}
void NextMovementState()
{
string methodName = movementState.ToString() + "State";
System.Reflection.MethodInfo info = GetType().GetMethod(methodName, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
StartCoroutine((IEnumerator)info.Invoke(this, null));
}
void NextCombatState ()
{
string methodName = combatState.ToString() + "State";
System.Reflection.MethodInfo info = GetType().GetMethod(methodName, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
StartCoroutine((IEnumerator)info.Invoke(this, null));
}
void NextViewState ()
{
string methodName = viewState.ToString() + "State";
System.Reflection.MethodInfo info = GetType().GetMethod(methodName, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
StartCoroutine((IEnumerator)info.Invoke(this, null));
}
void NextFleeState()
{
string methodName = viewState.ToString() + "State";
System.Reflection.MethodInfo info = GetType().GetMethod(methodName, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
StartCoroutine((IEnumerator)info.Invoke(this, null));
}
void Update()
{
Debug.DrawLine(transform.position, transform.position+transform.forward*5, Color.red);
if (fleeBool == true)
{
flee = true;
}
if (flee == true)
{
Debug.Log ("flee is true");
combatState = CombatState.CIdle;
movementState = MovementState.MIdle;
viewState = ViewState.VIdle;
Debug.Log ("End of idles");
}
}
}
You can use GameObject.FindObjectsOfType() or GameObject.FindGameObjectsWithTag
you can do that with store all the AIClass into array and then loop it become specific, so every enemy can affected
AIClass[] AIObject = GameObject.Find("Enemy").GetComponents<AIClass>();
foreach(AIClass a in AIObject ){
//do something with a
}
it should work.

Categories