오브젝트 풀링(원하는 스폰지역을 직접 만들어서 넣어주고 랜덤으로 소환)
- 목차
728x90
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MonsterSpawner : MonoBehaviour
{
public Transform[] spawnPoints; // 스폰 위치 배열
public GameObject[] monsterPrefabs; // 몬스터 프리팹 배열
public float spawnInterval = 3f; // 몬스터 스폰 간격
public float initialSpawnDelay = 2f; // 초기 스폰 지연 시간
private List<GameObject> monsterPool; // 몬스터 오브젝트 풀
private List<int> availableSpawnPoints; // 스폰 가능한 위치 인덱스 리스트
private void Start()
{
// 몬스터 오브젝트 풀 초기화
monsterPool = new List<GameObject>();
// 몬스터를 초기에 전부 스폰
SpawnAllMonsters();
// 스폰 가능한 위치 인덱스 리스트 초기화
availableSpawnPoints = new List<int>();
for (int i = 0; i < spawnPoints.Length; i++)
{
availableSpawnPoints.Add(i);
}
// 초기 스폰 지연 시간 후 몬스터 스폰 시작
Invoke("StartSpawning", initialSpawnDelay);
}
private void StartSpawning()
{
StartCoroutine(SpawnMonsters());
}
private void SpawnAllMonsters()
{
foreach (Transform spawnPoint in spawnPoints)
{
// 몬스터를 오브젝트 풀에서 가져오거나 생성
GameObject monster = GetOrCreateMonsterFromPool();
// 몬스터를 스폰 위치에 스폰
monster.transform.position = spawnPoint.position;
monster.SetActive(true);
}
}
private IEnumerator SpawnMonsters()
{
while (true)
{
yield return new WaitForSeconds(spawnInterval);
// 스폰 가능한 위치가 있는지 확인
if (availableSpawnPoints.Count == 0)
continue;
// 스폰 위치 인덱스를 랜덤하게 선택
int spawnIndex = Random.Range(0, availableSpawnPoints.Count);
int spawnPointIndex = availableSpawnPoints[spawnIndex];
// 해당 스폰 위치에 몬스터가 이미 스폰되어 있는지 확인
if (IsMonsterSpawnedAtPoint(spawnPointIndex))
continue;
// 몬스터를 오브젝트 풀에서 가져오거나 생성
GameObject monster = GetOrCreateMonsterFromPool();
// 몬스터를 선택된 스폰 위치에 스폰
monster.transform.position = spawnPoints[spawnPointIndex].position;
monster.SetActive(true);
// 스폰된 위치 인덱스를 스폰 가능한 위치 인덱스 리스트에서 제거
availableSpawnPoints.RemoveAt(spawnIndex);
}
}
private bool IsMonsterSpawnedAtPoint(int spawnPointIndex)
{
// 해당 스폰 위치에 몬스터가 있는지 확인하는 로직을 구현
// 이미 몬스터가 있다면 false를 반환하고, 없다면 true를 반환하여 스폰을 진행
bool hasMonster = false;
// 해당 스폰 위치에 몬스터가 있는지 검사
// 예시에서는 monsterPool 리스트를 사용하여 해당 위치의 몬스터 유무를 판단
GameObject monster = monsterPool.Find(m => m != null && m.activeSelf && m.transform.position == spawnPoints[spawnPointIndex].position);
if (monster == null)
{
hasMonster = true;
}
return hasMonster;
}
// 몬스터를 오브젝트 풀에서 가져오거나 생성
private GameObject GetOrCreateMonsterFromPool()
{
GameObject monster = monsterPool.Find(m => !m.activeSelf);
if (monster == null)
{
// 모든 몬스터 프리팹을 순회하며 오브젝트 풀에 추가
foreach (GameObject monsterPrefab in monsterPrefabs)
{
GameObject newMonster = Instantiate(monsterPrefab);
newMonster.SetActive(false);
monsterPool.Add(newMonster);
}
// 다시 몬스터를 가져옴
monster = monsterPool.Find(m => !m.activeSelf);
}
return monster;
}
}
728x90
'유니티,Unity,C#' 카테고리의 다른 글
유니티 빌드본(PC) 강제 종료 막기(Application.wantsToQuit) (1) | 2023.12.05 |
---|---|
유로 Assets DamageNumbersPro 리뷰 (1) | 2023.10.29 |
유니티 json데이터 암호화하는법(AES암호화방식) (1) | 2023.05.20 |
몬스터를 소환하고 정해진 루트로 이동하게 하는 스크립트 (0) | 2023.04.24 |
몬스터가 정해진 루트로 이동하는 스크립트 (0) | 2023.01.05 |