- 발판구현
- OnEnable() 메서드
- 발판 생성기 구현
- 오브젝트 풀링
- 미리 생성된 발판을 재사용하는 방법
@ 발판 만들기
- 시작지점 이후의 발판을 캐릭터가 밟을 경우 점수가 올라가는 기능 구현
- 발판 위에 장애물 생성하는 기능 구현
프리팹으로 생성한 오브젝트의 레이어를 설정해준다.
장애물 오브젝트는 배경보다는 앞에, 캐릭터와 발판보다는 뒤에 Middle 레이어로 변경
@ OnEnable() 메서드
: 컴포넌트가 활성화될 때마다 매번 다시 실행.
컴포넌트를 끄고 다시 켜는 방식으로 재실행 할 수 있음.
- 개별 컴포넌트를 끄고 켜지 않고, 게임오브젝트를 끄고 켜는 방식으로도 재실행 가능.
활용 : 게임 오브젝트가 활성화될 때마다 상태를 리셋하는 기능을 구현할 때 주로 이용. OnEnable()에 초기화 코드를 넣어두고, 게임 오브젝트의 정보를 리셋해야 할 때마다 게임 오브젝트를 끄고 다시 켜는 방식으로 활용.
// 컴포넌트가 활성화될때 마다 매번 실행되는 메서드
private void OnEnable() {
// 발판을 리셋하는 처리
// 밟힘 상태를 리셋
stepped = false;
// 장애물 수 만큼 루프
for ( int i = 0; i < obstacles.Length; i++ )
{
// 현재 순번의 장애물을 1/3의 확률로 활성화
if( Random.Range(0,3) == 0 )
{
obstacles[i].SetActive(true);
}
else
{
obstacles[i].SetActive(false);
}
}
}
밟힘상태를 false로 초기화한후, 순번 i를 0부터 시작해 장애물 수 obstacles.Length에 도달하기 전까지 1씩 증가시킴.
그뒤 1/3 확률로 장애물 오브젝트 활성화.
- Random.Range(0,3)은 0,1,2 중에서 한 숫자를 랜덤으로 반환.
@ 발판 밟으면 점수 추가
void OnCollisionEnter2D(Collision2D collision) {
// 플레이어 캐릭터가 자신을 밟았을때 점수를 추가하는 처리
// 충돌한 태그가 Player이고, 캐릭터가 이전에 밟지 않았다면
if (collision.collider.tag == "Player" && stepped == false )
{
// 점수를 추가하고 밟힘 상태를 true로 변경
stepped = true;
GameManager.instance.AddScore(1); // 1점 추가
}
}
같은 발판을 여러번 밟아서 점수 올라가는 것을 방지하기 위해 아직 안밟힌 발판인지 조건문에 추가 한 후 점수 추가
오브젝트 변경 한게 있으면 프리팹 선택후 Overrides > Apply All 클릭해서 프리팹에 반영 시킴.
@ 발판 생성기 만들기 ( 오브젝트 풀링 )
오브젝트 풀링 : 초기에 필요한 만큼 오브젝트를 미리 만들어 풀에 쌓아두는(저장해 놓는) 방식.
- 오브젝트가 필요할 때에는 오브젝트를 풀에서 가져다 씀.
- 오브젝트가 필요 없을 때에는 오브젝트를 파괴하지 않고 비활성화하고 풀에 반환.
Instantiate() 메서드 처럼 오브젝트를 실시간으로 생성하거나, Destroy() 메서드처럼 오브젝트를 실시간으로 파괴하는 처리는 성능을 많이 요구함.
또 메모리를 정리하는 GC( 가비지 컬렉션 )를 유발하기 쉬움. => 생성 및 삭제가 많아질수록 끊김 현상 발생
오브젝트 풀링은 게임 초반에 미리 생성함 => 로딩 시간이 길어짐. => 대신 게임 끊김 현상은 거의 없음.
@ PlatformSpawner 스크립트 작성하기
using UnityEngine;
// 발판을 생성하고 주기적으로 재배치하는 스크립트
public class PlatformSpawner : MonoBehaviour {
public GameObject platformPrefab; // 생성할 발판의 원본 프리팹
public int count = 3; // 생성할 발판의 개수
public float timeBetSpawnMin = 1.25f; // 다음 배치까지의 시간 간격 최솟값
public float timeBetSpawnMax = 2.25f; // 다음 배치까지의 시간 간격 최댓값
private float timeBetSpawn; // 다음 배치까지의 시간 간격
public float yMin = -3.5f; // 배치할 위치의 최소 y값
public float yMax = 1.5f; // 배치할 위치의 최대 y값
private float xPos = 20f; // 배치할 위치의 x 값
private GameObject[] platforms; // 미리 생성한 발판들
private int currentIndex = 0; // 사용할 현재 순번의 발판
private Vector2 poolPosition = new Vector2(0, -25); // 초반에 생성된 발판들을 화면 밖에 숨겨둘 위치
private float lastSpawnTime; // 마지막 배치 시점
void Start() {
// 변수들을 초기화하고 사용할 발판들을 미리 생성
// count만큼의 공간을 가지는 새로운 발판 배열 생성
platforms = new GameObject[count];
// count만큼 루프하면서 발판 생성
for( int i = 0; i < count; i++ )
{
// platformPrefab을 원본으로 새 발판을 poolPosition 위치에 복제 생성
// 생성된 발판을 platform 배열에 할당
platforms[i] = Instantiate(platformPrefab, poolPosition, Quaternion.identity);
}
// 마지막 배치 시점 초기화
lastSpawnTime = 0f;
// 다음번 배치까지의 시간 간격을 0으로 초기화
timeBetSpawn = 0f;
}
void Update() {
// 순서를 돌아가며 주기적으로 발판을 배치
// 게임오버 상태에서는 동작하지 않음
if (GameManager.instance.isGameover)
{
return;
}
// 마지막 배치 시점에서 timeBetSpawn 이상 시간이 흘렀다면
if ( Time.time >= lastSpawnTime + timeBetSpawn)
{
// 기록된 마지막 배치 시점을 현재 시점으로 갱식
lastSpawnTime = Time.time;
// 다음 배치까지의 시간 간격을 timeBetSpawnMin, timeBetSpawnMax 사이에서 랜덤 설정
timeBetSpawn = Random.Range(timeBetSpawnMin, timeBetSpawnMax);
// 배치할 위치의 높이를 yMin과 yMax 사이에서 랜덤 설정
float yPos = Random.Range(yMin, yMax);
// 사용할 현재 순번의 발판 게임 오브젝트를 비활성화하고 즉시 다시 활성화 => 초기화 시킴
// 이때 발판의 Platform 컴포넌트의 OnEnable 메서드가 실행됨
platforms[currentIndex].SetActive(false);
platforms[currentIndex].SetActive(true);
// 현재 순번의 발판을 화면 오른쪽에 재배치
platforms[currentIndex].transform.position = new Vector2 (xPos, yPos);
//순번 넘기기
currentIndex++;
// 마지막 순번에 도달했다면 순번을 리셋
if (currentIndex >= count)
{
currentIndex = 0;
}
}
}
}
Time.time은 유니티 라이브러리에 내장되어 있으며, 게임 시작 후 시간이 몇 초 지났는지 출력하는 변수.
- 따라서 현재시점으로 취급할 수 있음.
lastSpawnTime + timeBetSpawn은 다음번 배치가 예약된 시점.
@ 배경음악 넣기
배경음악 파일을 넣고 - 루프 체크.
@ 빌드하기
Add Open Scenes 눌러준 후 Build And Run으로 폴더 선택 후 빌드!
14장. 좀비 서바이벌(라이트 맵, 글로벌 일루미네이션 GI) (0) | 2024.04.02 |
---|---|
카메라 이동제한 시키기(시네머신) (0) | 2024.03.29 |
13장 유니런(게임매니저, 싱글톤 패턴) (0) | 2024.03.22 |
12장 유니런(배경스크롤링) (0) | 2024.03.21 |
11장 유니런(1) (0) | 2024.03.15 |