EnemyManager - 적 생성
적을 랜덤한 위치에 n초마다 오브젝트 풀에서 가져와 생성하고, 오브젝트 풀에서 모두 SetActive(true)된 상태면 추가로 생성하지 않는다.
맵 사방에서 랜덤한 위치에 생성된 Enemy가 로직대로 움직이지 않았다.
플레이어를 끝까지 추적하는 적(TracingEnemy)은 생성되면서 이동 속도가 계속 느려졌고,
플레이어와 일정 거리로 가까워지면 주변에서 원형으로 도는 적(HoveringEnemy)은 특정 거리에 도달해도 원형으로 돌지 않고 플레이어 위치까지 이동했다.
EnemyManager를 적용하여 랜덤 생성한 경우에만 버그가 발생했다.
처음에 적을 사방에서 생성하기 위해 enemySpawnPoint에 상하좌우 4개의 Camera의 자식으로 만든 Object를 추가하여 네 방향 중 하나를 랜덤하게 선택하고(SelectRandomSpawnPoint()), 그 지점에서 -10~10 범위에서 랜덤한 위치를 정하는(RandomSpawnRange()) 방식으로 작성했다.
private Transform SelectRandomSpawnPoint()
{
int index = Random.Range(0, 4);
return enemySpawnPoint[index].transform;
}
private Transform RandomSpawnRange()
{
float range = Random.Range(-10, 10);
Transform randomSpawnTransform = SelectRandomSpawnPoint();
randomSpawnTransform.position = randomSpawnTransform.position + new Vector3(range, range, 10);
return randomSpawnTransform;
}
문제1. z축 방향에 대해 부주의함
위의 코드를 보면 위치를 랜덤하게 설정하기 위해 Transform.position으로 값을 가져오는 것을 알 수 있는데, 그 값에 z축 값이 설정되어 있었고, player와 enemy의 z축 값이 달라서 오류가 발생하였다.
문제2. Transform은 참조형
enemySpawnPoint[index].transform을 return으로 받아 사용하면서 문제가 발생했다. RandomSpawnRange()의 return인 randomSpawnTransform은 enemySpawnPoint[index].transform을 가리키고 있고, 이 transform에 new Vector3(range, range, 10)을 더하면서 enemySpawnPoint[index].transform의 값이 계속 바뀌게 되면서(특히 z값) 문제가 발생하였다. (z의 10을 더한 이유는 Camera의 포지션이 z -10이었기 때문)
Transform으로 받아오지 않고 Vector2로 position 값을 return 받아 z값을 무시하고 적용하였다.
public class EnemyManager : MonoBehaviour
{
public static EnemyManager Instance;
public ObjectPool EnemyObjectPool { get; private set; }
[SerializeField] private GameObject[] enemySpawnPoint;
[SerializeField] private string enemyTag;
[SerializeField] private float spawnDelayTime;
private bool isSpawn = true;
private void Awake()
{
if (Instance != null)
{
Destroy(gameObject);
}
Instance = this;
EnemyObjectPool = GetComponent<ObjectPool>();
}
private void Update()
{
if (isSpawn)
{
isSpawn = false;
StartCoroutine(MakeEnemy());
}
}
IEnumerator MakeEnemy()
{
if (EnemyObjectPool.PoolDictionary[enemyTag].Any(x => x.activeSelf == false))
{
GameObject obj = EnemyObjectPool.GetObjectFromPool(enemyTag);
obj.transform.position = RandomSpawnInRange();
}
yield return new WaitForSeconds(spawnDelayTime);
isSpawn = true;
}
private Vector2 SelectRandomSpawnPoint()
{
int index = Random.Range(0, 4);
return enemySpawnPoint[index].transform.position;
}
private Vector2 RandomSpawnInRange()
{
float range = Random.Range(-10, 10);
Vector2 randomPosition = SelectRandomSpawnPoint();
randomPosition = randomPosition + new Vector2(range, range);
return randomPosition;
}
}