뜨는 오류
Coroutine couldn't be started because the the game object 'Enemy_Dummy_Layer1' is inactive!
UnityEngine.MonoBehaviour:StartCoroutine (System.Collections.IEnumerator)
Enemy:SpawnSetup (EnemySpawner,UnityEngine.Transform[],EnemyType) (at Assets/Scripts/Enemies/Default/Enemy.cs:92)
LayerSystem:SpawnLowLayer () (at Assets/Scripts/Enemies/Special/LayerSystem.cs:21)
EnemyHP:TakeDamage (single,bool,bool) (at Assets/Scripts/Enemies/Default/EnemyHP.cs:82)
TowerAttack/<TryAttackLaser>d__69:MoveNext () (at Assets/Scripts/Tower/Tower_Movement/TowerAttack.cs:420)
UnityEngine.SetupCoroutine:InvokeMoveNext (System.Collections.IEnumerator,intptr)
public class LayerSystem : MonoBehaviour
{
[SerializeField]
GameObject spawnLayer;
[SerializeField]
Enemy myData;
public void SpawnLowLayer()
{
GameObject spawnObject = Instantiate(spawnLayer);
spawnObject.transform.position = transform.position;
Enemy mySpawn = spawnLayer.GetComponent<Enemy>();
spawnObject.SetActive(true);
mySpawn.SpawnSetup(myData.spawner, myData.wayPoints, myData.enemyType);
mySpawn.currentIndex = myData.currentIndex;
mySpawn.wayPointCount = myData.wayPointCount;
mySpawn.wayPoints = myData.wayPoints;
myData.spawner.enemyList.Add(mySpawn);
myData.spawner.SpawnEnemyHPSlider(spawnObject);
myData.OnDie(EnemyDestoryType.Killed);
}
}
public enum EnemyType { Normal, Stealth, SlowImmunity, SplashImmunity, OverArmored, Doped, Regeneration, Boosted }
public enum EnemyDestoryType { Killed = 0, Arrive }
public class Enemy : MonoBehaviour
{
public EnemyType enemyType;
[HideInInspector]
public int wayPointCount;
[HideInInspector]
public Transform[] wayPoints;
[HideInInspector]
public int currentIndex = 0;
[HideInInspector]
public Movement movement;
[HideInInspector]
public EnemySpawner spawner;
public int GetCurrentIndex()
{
return currentIndex;
}
public int GetWayPointLength()
{
return wayPoints.Length;
}
public Transform GetWayPointTransform(int index)
{
return wayPoints[index];
}
public Transform GetNextWayPointTransform()
{
int nextIndex = GetCurrentIndex() + 1;
// 마지막 웨이포인트에 도달했을 때는 null 반환
if (nextIndex >= GetWayPointLength())
{
return null; // 다음 웨이포인트가 없으므로 null 반환
}
return GetWayPointTransform(nextIndex);
}
[SerializeField]
int reward = 10;
public void SetUp(EnemySpawner enemySpawner, Transform[] wayPoints, EnemyType enemyType = EnemyType.Normal)
{
movement = GetComponent<Movement>();
spawner = enemySpawner;
this.enemyType = enemyType;
if (enemyType == EnemyType.Boosted)
{
movement.MoveSpeed *= 2;
movement.SetBaseSpeed();
}
wayPointCount = wayPoints.Length;
this.wayPoints = new Transform[wayPointCount];
this.wayPoints = wayPoints;
transform.position = wayPoints[currentIndex].position;
StartCoroutine(OnMove());
}
public void SpawnSetup(EnemySpawner enemySpawner, Transform[] wayPoints, EnemyType enemyType = EnemyType.Normal)
{
movement = GetComponent<Movement>();
spawner = enemySpawner;
this.enemyType = enemyType;
if (enemyType == EnemyType.Boosted)
{
movement.MoveSpeed *= 2;
movement.SetBaseSpeed();
}
this.wayPoints = new Transform[wayPointCount];
this.wayPoints = wayPoints;
this.gameObject.SetActive(true);
if (!gameObject.activeInHierarchy)
{
StartCoroutine(OnMove());
}
}
IEnumerator OnMove()
{
NextMoveTo();
while (true)
{
if (Vector3.Distance(transform.position, wayPoints[currentIndex].position) < 0.02f * movement.MoveSpeed)
{
NextMoveTo();
}
yield return null;
}
}
void NextMoveTo()
{
if (currentIndex < wayPointCount - 1)
{
transform.position = wayPoints[currentIndex].position;
currentIndex++;
Vector3 direction = (wayPoints[currentIndex].position - transform.position).normalized;
movement.MoveTo(direction);
}
else
{
reward = 0;
OnDie(EnemyDestoryType.Arrive);
}
}
public void OnDie(EnemyDestoryType type)
{
spawner.KillEnemy(type, this, reward);
}
}
public class EnemyHP : MonoBehaviour
{
[SerializeField]
float maxHP;
public float defensive;
float currentHP;
bool isDie = false;
bool isRegenerating = false;
bool isDoped = false;
[Header("Death Effect")]
[SerializeField]
LayerSystem layerSystem = null;
[Header("Data")]
[SerializeField]
Enemy enemy;
public float MaxHP => maxHP;
public float CurrentHP => currentHP;
private void Awake()
{
currentHP = maxHP;
}
IEnumerator RegenHP()
{
isRegenerating = true;
while (true)
{
yield return new WaitForSeconds(1f);
if (currentHP < maxHP)
currentHP += maxHP / 50;
else
currentHP = maxHP;
}
}
void HealthDouble()
{
isDoped = true;
maxHP *= 2;
currentHP = maxHP;
}
public void TakeDamage(float damage, bool isArmorPierce = false, bool isOverArmorBreak = false)
{
if (isDie)
return;
if (enemy.enemyType == EnemyType.Doped && !isDoped)
HealthDouble();
if (defensive != 0 && !isArmorPierce)
damage *= defensive;
if (enemy.enemyType == EnemyType.OverArmored && !isOverArmorBreak)
{
if (damage > 1)
damage = 1;
}
currentHP -= damage;
if (enemy.enemyType == EnemyType.Regeneration && !isRegenerating)
StartCoroutine(RegenHP());
if (currentHP <= 0)
{
isDie = true;
if (layerSystem != null)
{
layerSystem.SpawnLowLayer();
return;
}
enemy.OnDie(EnemyDestoryType.Killed);
}
}
}
( Tower Attack 스크립트는 그냥 데미지 주는데서 저 코루틴 문제 때문에 생긴 별개의 오류라 안 달음 )
에러 로그를 보면 LayerSystem을 가진 적이 죽으면 등록해둔 프리팹을 스폰하고
프리팹의 Enemy 스크립트에서 OnMove쪽의 코루틴을 실행하는데 거기서 문제가 생김.
검색 해보니까 코루틴 실행전에 오브젝트가 비활성화 되어있으면 생기는 오류라는데 비활성화 되게 한적도 없고
코루틴 실행 직전에 오브젝트 활성화 코드를 넣어도 자꾸 같은 오류가 뜸.
코루틴 맨 윗줄에 yield return new WaitForSeconds(0.02f); 넣어보셈
안 됨. 자세한 오류 문구들이랑 거기서 언급된 자잘한 코드 글에 추가함.
var spawnObject = Instantiate(spawnLayer, transform.position, Quaternion.identity); var mySpawn = spawnObject.GetComponent<Enemy>(); 로 바꿔보셈
됐다..!
궁금한데 프리팹에서 코루틴이 실행되는거야?
평범하게 적 프리팹 소환하면 잘만 되는데 적이 적을 소환할땐 안돼서 그럼
Enemy mySpawn = spawnLayer.GetComponent(); 이걸 보면 소환된 객체가 아니라 프리팹 에셋에서 콤포넌트 얻어와서 코루틴 실행하는 거 같아서.
정답자에게 합격의 목걸이를 ㄷㄷ
오예!