foreach code causes lag spike C#

sorry about making another question but everytime i fix somthing another thing breaks, in this script, foreach at line 40 is making a huge lag spike any ideas on a fix? btw im sorry about the messy code, i only started learning this less than a week ago by my self.

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

public class PistolRay : MonoBehaviour {

	bool canFire = true;
	public GameObject decal;
	public float clipAmmo = 8;
	public float storedAmmo = 80;
	float missingShots = 0;
	GameObject player;
	GameObject characterControler;
	bool reloading = false;
	private List<EnemyAi> enemies = new List<EnemyAi>();

	// Use this for initialization
	void Start () {

	}
	
	// Update is called once per frame
	void Update () {
		player = GameObject.Find("Player");
		CharacterControler characterControler = player.GetComponent<CharacterControler>();
		characterControler.ammoCount = clipAmmo;
		characterControler.totalAmmo = storedAmmo;
		var enemyObjects = GameObject.FindGameObjectsWithTag("Enemy");
		foreach(GameObject enemyObj in enemyObjects){
			EnemyAi enemyAi = enemyObj.GetComponent<EnemyAi>();
			if(enemyAi != null){
		enemies.Add(enemyAi);
		}
		}
		RaycastHit hit;
		Ray shooterRay = new Ray(transform.position, transform.forward);

		if(Input.GetButton("Fire1") && canFire && clipAmmo > 0){
			if(GameObject.Find ("EnemyAi") != null){
				foreach(EnemyAi enemy in enemies){
			EnemyAi enemyAi = enemy.GetComponent<EnemyAi>();
			enemyAi.couldHearGun = true;
			StartCoroutine (SoundCooldown(1));
			}
		}
		}
		if(Input.GetButton("Fire1") && canFire && clipAmmo > 0){
			Debug.DrawRay (transform.position, transform.forward, Color.green);
				if(Physics.Raycast(shooterRay, out hit, Mathf.Infinity)){
				if(hit.collider.tag == "Enemy"){
					hit.transform.GetComponent<EnemyCC>().health -= 15;
				}
			}
			var hitRotation = Quaternion.FromToRotation(Vector3.up, hit.normal);
			Instantiate(decal, hit.point, hitRotation);	
			canFire = false;
			clipAmmo -= 1;
			missingShots += 1;
			StartCoroutine(FireRate(1));
			}
		if(Input.GetButtonDown("Fire1") && canFire && clipAmmo == 0 && !reloading){
			reloading = true;
			StartCoroutine(ReloadTime(3));
		}

		if(Input.GetButtonDown("Reload") && storedAmmo != 8 && !reloading){
			reloading = true;
			StartCoroutine(ReloadTime(3));
		}
		}
	public IEnumerator FireRate (float delay){
		yield return new WaitForSeconds(delay);
		canFire = true;
	}
	public IEnumerator SoundCooldown(float delay){
		GameObject enemy = GameObject.Find("EnemyAI");
		EnemyAi enemyAi = enemy.GetComponent<EnemyAi>();
		yield return new WaitForSeconds(delay);
		enemyAi.couldHearGun = false;

	}
	public IEnumerator ReloadTime (float delay){
		yield return new WaitForSeconds(delay);
		reloading = false;
		if(storedAmmo >= 8){
			storedAmmo -= missingShots;
			clipAmmo += missingShots;
			missingShots = 0;
		}
	}
}

My money would be on your call(s) to GameObject.Find (). GameObject.Find() isn’t the most efficient method, plus you are calling it multiple times since you have it in Update(); If you’re going to use it do it in Start().

The player for example:

player = GameObject.Find("Player");

You don’t need to do this every frame, but only once at start and the same goes for getting the CharacterController.

If you are creating enemies dynamically and need a reference to all the enemies in the game use some sort of object pooling and store a reference to a List of the enemies rather than trying to find them each frame.

Sorry to waste peoples time but i got it now, StartCoroutine(SoundCooldown(1)); was firing off for every enemy in the scene, all i had to do was move it out of the foreach section. i an such an idiot sometimes :stuck_out_tongue: