해당 게임은 이제민 저자의 ‘레트로의 유니티 게임 프로그래밍 에센스’ 를 기반으로 제작되었음을 밝힙니다.

게임 소개 및 기능

유니티를 통해 간단한 2D 러너 게임을 만들어보았다.

게임의 기능은 다음과 같다.

  1. 발판은 무한히 생성되며, 발판의 높이 및 간격은 랜덤으로 생성된다. 발판 위 장애물 또한 1~3개가 랜덤으로 생성된다.
  2. 캐릭터는 점프를 통해 발판을 뛰어다니며, 장애물을 피할 수 있다.
  3. 점프 버튼을 누르는 시간에 따라 점프 높이를 조절할 수 있다. 길게 누를수록 높이 점프한다.
  4. 플레이어는 뛰기, 점프, 사망 애니메이션이 상황에 따라 적용된다.

게임 구현

1. 오브젝트 생성

플레이어 모델은 UnityChan.com 에서 무료로 배포하는 캐릭터 스프라이트를 사용했다.

UniRun_1

플레이어가 밝게 될 블록 오브젝트, 장애물 오브젝트는 다음과 같이 구현됐다.

UniRun_2

2. 플레이어 애니메이션

캐릭터 스프라이트를 적절히 슬라이스하고 연결하여 뛰기, 점프, 사망 3개의 애니메이션 클립을 만들었다. UniRun1 UniRun2 UniRun2

3. 플랫폼의 이동 및 무한 생성

캐릭터가 직접 오른쪽으로 움직이지 않고 플랫폼이 왼쪽으로 움직이는 방식을 선택했다.

// 게임 오브젝트를 계속 왼쪽으로 움직이는 스크립트
public class ScrollingObject : MonoBehaviour
{
    public float speed = 10f; // 이동 속도

    private void Update()
    {
        // 게임 오브젝트를 왼쪽으로 일정 속도로 평행 이동하는 처리
        if (!GameManager.instance.isGameOver())
        {
            transform.Translate(Vector3.left * speed * Time.deltaTime);
        }
    }
}

플레이어를 향해 계속 움직여야 하는 스카이박스, 플랫폼에 위 스크립트를 추가해줬다.

플랫폼이 무한히 생성될 수 있도록 미리 3개의 블록을 생성해놓고, 계속 이어서 재사용 하는 방식의 플랫폼 스크립트와 플랫폼 생성 스크립트를 작성했다.

//Platform.cs
public GameObject[] obstacles; // 장애물 오브젝트들
private bool stepped = false; // 플레이어 캐릭터가 밟았었는가
// 컴포넌트가 활성화될때 마다 매번 실행되는 메서드
private void OnEnable()
{
    // 발판을 리셋하는 처리
    stepped = false;
    for (int i = 0; i < obstacles.Length; i++)
    {
        if (Random.Range(0, 3) == 0)
        {
            obstacles[i].SetActive(true);
        }
        else
        {
            obstacles[i].SetActive(false);
        }
    }
}

위 코드에서는 플랫폼 본인이 활성화될 때마다 장애물의 위치를 매번 랜덤으로 지정해준다.

//PlatformSpawner.cs
void Start()
    {
        // 변수들을 초기화하고 사용할 발판들을 미리 생성
        platforms = new GameObject[count];
        for (int i = 0; i < count; i++)
        {
            platforms[i] = Instantiate(platformPrefab, poolPosition, Quaternion.identity);
        }
        lastSpawnTime = 0f;
        timeBetSpawn = 0f; //발판 생성 주기
    }

    void Update()
    {
        // 순서를 돌아가며 주기적으로 발판을 배치
        if (GameManager.instance.isGameOver())
        {
            return;
        }
        if (Time.time >= lastSpawnTime + timeBetSpawn)
        {
            lastSpawnTime = Time.time;
            timeBetSpawn = Random.Range(timeBetSpawnMin, timeBetSpawnMax);
            float yPos = Random.Range(yMin, yMax); //발판의 높이를 랜덤으로 지정
            platforms[currentIndex].SetActive(false);
            platforms[currentIndex].SetActive(true);
            platforms[currentIndex].transform.position = new Vector2(xPos, yPos);

            if (++currentIndex >= count)
            {
                currentIndex = 0;
            }
        }
    }

4. UI

게임 스코어 및 게임오버 UI를 만들어주고, 게임매니저 스크립트를 통해 관리해준다.

UniRun_3

///GameManager.cs
void Update()
{
    // 게임 오버 상태에서 게임을 재시작할 수 있게 하는 처리
    if (_isGameover && Input.GetMouseButtonDown(0))
    {
        SceneManager.LoadScene(SceneManager.GetActiveScene().name);
    }
}
// 점수를 증가시키는 메서드
public void AddScore(int newScore)
{
    if (!_isGameover)
    {
        score += newScore;
        scoreText.text = "Score : " + score;
    }
}
// 플레이어 캐릭터가 사망시 게임 오버를 실행하는 메서드
public void OnPlayerDead()
{
    _isGameover = true;
    gameoverUI.SetActive(true);
}
public bool isGameOver()
{
    return _isGameover;
}

게임매니저의 AddSocre() 메서드는 플랫폼 스크립트에서 플레이어가 새로운 발판을 밟을 시 호출된다.

//Platform.cs
void OnCollisionEnter2D(Collision2D collision)
 {
     // 플레이어 캐릭터가 자신을 밟았을때 점수를 추가하는 처리
     if (collision.collider.tag == "Player" && !stepped)
     {
         stepped = true;
         GameManager.instance.AddScore(1);
     }
 }

5. 실행 결과

태그: ,

카테고리:

업데이트:

댓글남기기