IEnumerator launchProjectiles() { //wait for 2 reasons: 1) enemy's position is set relatively late (might provide wrong source loc for projectile) //2) more fair to start launch projectile after enemy visually shows up in screen yield return(new WaitUntil(() => Global.gameObjectInView(transform))); while (true) { if (genProjectile && projectileSprite && Global.percentChance((int)(shootChanceIndividual * 100))) { GameObject p = Instantiate(myProjectilePrefab, this.transform.localPosition, myProjectilePrefab.transform.rotation); p.transform.parent = null; p.SetActive(true); p.GetComponent <SpriteRenderer>().sprite = projectileSprite; Destroy(p.GetComponent <CircleCollider2D>()); CircleCollider2D circ = p.AddComponent <CircleCollider2D>(); //TODO check here; supposedly auto generates appropriately sized collider circ.isTrigger = true; p.transform.localScale = transform.lossyScale; projectile proj = p.GetComponent <projectile>(); proj.damage = projectileAttack; proj.setSpeed(projectileSpeed); proj.setAcceleration(projectileAccl); Vector3 direction = Vector3.down; float angle = 0; bool rotateProjectile = false; switch (projectileType) { case 0: break; case 1: direction = gameControl.player.transform.position - transform.position; float tan = direction.x / direction.y; angle = Mathf.Atan(tan); if (direction.y > 0) { Destroy(proj); //if player is above, this type of projectile will not be launched } rotateProjectile = true; break; } if (proj) { proj.setDirection(direction, angle, rotateProjectile); } } //effectively, noise = 0.2 will make shoot time range from 0.8x to 1.2x yield return(new WaitForSeconds(shootInterval + Random.Range(-shootNoise, shootNoise) * shootInterval)); } }