How to end this infinite loop problem in C#!?

SO, pretty much i tried to make a script which made the enemy approach the target (player) and stopped at a distance. Now i wanted the enemy to hit me after a few second intervals. I dunno what went wrong, but apparently something did, thats why i am running an infinte…

please help, here is the code

using UnityEngine;
using System.Collections;

public class AI : MonoBehaviour {
	public Transform target;
	public float moveSpeed = 50f;
	float pos1, pos2;
	float playerHealth;
	public float attackSpeed = 1;

	// Use this for initialization
	void Start () {
		playerHealth = target.GetComponent<hp>().curHealth;
	}
	
	// Update is called once per frame
	void Update () 
	{
		Vector3 pos1 = target.transform.position;
		Vector3 pos2 = gameObject.transform.position;
		if (Vector3.Distance (pos1, pos2) < 10 && Vector3.Distance (pos1, pos2) > 2) 
		{
			transform.LookAt(target);
			gameObject.transform.position += gameObject.transform.forward * moveSpeed * Time.deltaTime; 
		}
		else if (Vector3.Distance (pos1, pos2) < 2 && Vector3.Distance (pos1, pos2) > 0) 
		{
			while (playerHealth > 0) {
				hit();
			}
		}
		
	}
	IEnumerator hit() 
	{
		playerHealth -= 5;
		yield return new WaitForSeconds (attackSpeed);
	}
}

Well, your while loop is a problem because of what you’re trying to do.

IEnumerators are designed to run asynchronous operations which is not how you’re using it. Seems like you want the player to keep taking damage while they’re in a specific location, but only every few seconds (I assume it’s like, standing in fire hurts every 2 seconds or something.)

Get rid of the while loop and keep track of the time manually.

using UnityEngine;
using System.Collections;
 
public class AI : MonoBehaviour {
    public Transform target;
    public float moveSpeed = 50f;
    float pos1, pos2;
    float playerHealth;
    public float attackSpeed = 1;
 
    public float lastAttackTime =0;

    // Use this for initialization
    void Start () {
        playerHealth = target.GetComponent<hp>().curHealth;
    }
 
    // Update is called once per frame
    void Update () 
    {
        Vector3 pos1 = target.transform.position;
        Vector3 pos2 = gameObject.transform.position;
        if (Vector3.Distance (pos1, pos2) < 10 && Vector3.Distance (pos1, pos2) > 2) 
        {
            transform.LookAt(target);
            gameObject.transform.position += gameObject.transform.forward * moveSpeed * Time.deltaTime; 
        }
        else if (Vector3.Distance (pos1, pos2) < 2 && Vector3.Distance (pos1, pos2) > 0) 
        {
            if(Time.time - lastAttackTime > attackSpeed)
            {
                lastAttackTime = Time.time;
                playerHealth -=5;
            }
        }
 
    }
}

I kind helped myself, i figured out that you cannot run IEnumerator functions cannot be run on update plainly, so i used StartCoroutine() kinda this::

else if (Vector3.Distance (pos1, pos2) < 1.5 && Vector3.Distance (pos1, pos2) > 0) 
		{
			while (playerHP.curHealth > 0) {
				hit();
			}
		}

was converted to this

else if (Vector3.Distance (pos1, pos2) < 1.5 && Vector3.Distance (pos1, pos2) > 0) 
		{
			while (playerHP.curHealth > 0) {
				StartCoroutine(hit());
			}
		}

Another way to achieve this would be to abandon Update altogether and just use a coroutine.

using UnityEngine;
using System.Collections;
 
public class AI : MonoBehaviour {
    public Transform target;
    public float moveSpeed = 50f;
    float playerHealth;
    public float attackSpeed = 1;
 
    // Use this for initialization
    void Start () {
        playerHealth = target.GetComponent<hp>().curHealth;
        StartCoroutine(Behaviour());
    }
 
    // Update is not used... 
    void Update () {}

    IEnumerator Behaviour () {
        while (true){
            while (Vector3.Distance (target.transform.position, gameObject.transform.position) < 10 && Vector3.Distance (target.transform.position, gameObject.transform.position) > 2){
                yeild return StartCouroutine(Move());
            }
            // Checking the player health first to avoid unneeded distance checks 
            while (playerHealth > 0 && Vector3.Distance (target.transform.position, gameObject.transform.position) < 2 && Vector3.Distance (target.transform.position, gameObject.transform.position) > 0){
                yeild return StartCoroutine(Hit());
            }
        yield return null;
        }
    }

    IEnumerator Hit() {
        playerHealth -= 5;
        yield return new WaitForSeconds (attackSpeed);
    }

    IEnumerator Move () {
        transform.LookAt(target);
        gameObject.transform.position += gameObject.transform.forward * moveSpeed * Time.deltaTime;
        yield return null; 
    }
}