[ 오브젝트 풀링으로 소환 ] --> 몬스터가 시간에 지남에 따라 자동으로 소환되는 기믹 만들기
- Prefabs 폴더 만들기 --> Hierachy의 Enemy 종류별로 Prefabs 안쪽에 드래그&드랍
(많은 종류의 오브젝트를 관리하는데 효과적) - Hierachy의 Enemy를 Prefabs 폴더에 저장했다면, Hierachy에서 삭제
- Hierachy에 Create Empty --> PoolManager(Prefabs을 관리)
- C# 스크립트 추가 -> PoolManager
ㅡ아래는 완성된 코드ㅡ
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PoolManager : MonoBehaviour{
public GameObject[] prefabs;
List<GameObject>[] pools;
private void Awake(){
pools = new List<GameObject>[prefabs.Length];
for(int index = 0; index < pools.Length; index++){
pools[index] = new List<GameObject>();
}
}
public GameObject Get(int index) {
GameObject select = null;
// ... 선택한 풀의 비활성화 된 게임 오브젝트 접근
foreach (GameObject item in pools[index]){
if (!item.activeSelf){
// ... 발견하면 select 변수에 할당
select = item;
select.SetActive(true);
break;
}
}
// ... 게임 오브젝트가 모두 활성화 되어 있다면?
if (!select){
// ... 새롭게 생성하고 select 변수에 할당
select = Instantiate(prefabs[index], transform); // 프리펩에 있는 오브젝트를 복사하여 변수에 할당
pools[index].Add(select); // 생성된 오브젝트를 풀 리스트에 Add 함수로 추가
}
return select;
}
}
- 기존 Enemy 스크립트에 코드 추가
ㅡ아래는 완성된 코드ㅡ
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy : MonoBehaviour
{
public float speed;
public float hp;
public float maxHp;
public RuntimeAnimatorController[] animCon;
public Rigidbody2D target;
bool isLive;
Rigidbody2D rigid;
Animator anim;
SpriteRenderer spriter;
void Awake()
{
rigid = GetComponent<Rigidbody2D>();
anim = GetComponent<Animator>();
spriter = GetComponent<SpriteRenderer>();
}
// Update is called once per frame
private void FixedUpdate(){
if (!isLive){
return;
}
Vector2 dirVec = target.position - rigid.position;
Vector2 nextVec = dirVec.normalized * speed * Time.fixedDeltaTime;
rigid.MovePosition(rigid.position + nextVec);
rigid.velocity = Vector2.zero;
}
private void LateUpdate()
{
if (!isLive){
return;
}
spriter.flipX = target.position.x < rigid.position.x;
}
private void OnEnable()
{
target = GameManager.instance.player.GetComponent<Rigidbody2D>(); // Enemy 스스로 플레이어를 타겟으로 초기화
}
}
- Hierachy의 Player\Spawner에 Create Empty --> Point(몬스터가 소환 될 지점)
- Point를 Scene 바깥을 빙 두르듯 배치(Ctrl + D로 복사)
- 기존의 Spawner 스크립트에 코드 추가
ㅡ아래는 완성된 코드ㅡ
using System.Collections;
using System.Collections.Generic;
using UnityEditor.ShaderGraph.Internal;
using UnityEngine;
public class Spawner : MonoBehaviour
{
public Transform[] spawnPoint; // spawnPoint의 위치를 받는 변수
float timer;
private void Awake()
{
spawnPoint = GetComponentsInChildren<Transform>(); // 자신(Spawner)을 포함한 자식 오브젝트(Point)의 위치를 받음
}
void Update()
{
timer += Time.deltaTime;
if (timer > 0.2f) // 일정 시간마다 소환
{
timer = 0;
Spawn(); // 소환 함수 호출
}
}
void Spawn() // 몬스터 소환 함수
{
GameObject enemy = GameManager.instance.pool.Get(0); // pool의 첫번째 엔트리를 enemy에 초기화
enemy.transform.position = spawnPoint[Random.Range(1, spawnPoint.Length)].position; // enemy가 소환되는 위치는 자신(Spawner)을 제외한 자식 오브젝트(Point) 중 랜덤한 위치
}
}
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
★Slow and Steady★
'Unity 공부 > Unity_2D' 카테고리의 다른 글
| [Day 5] 회전하는 근접무기 구현 (0) | 2023.07.11 |
|---|---|
| [Day 4] 소환 레벨 적용 (2) | 2023.07.10 |
| [Day 2] 몬스터 제작 (0) | 2023.07.08 |
| [Day 1] 2D 오브젝트 제작 | 플레이어 이동 구현 | 2D 셀 애니메이션 제작 | 무한 맵 이동 (0) | 2023.07.07 |
| Project_Moon 입사를 꿈꾸며.... (0) | 2023.06.23 |