9/27 Flappy Bird 비슷한 게임 #2

Hongryeol In·2024년 9월 27일

멋사유니티TIL

목록 보기
2/3
post-thumbnail

충돌

새에 콜리전과 리지드바디 추가

새와 벽에 Collider2D를 추가합니다.

콜라이더 크기를 새에 적당히 맞춰줍니다.


새에 RigidBody2D를 추가합니다.

RigidBody는 오브젝트를 물체화시킵니다.

  • 중력
  • 충돌

등등을 적용받을 수 있게 해주는 컴포넌트입니다.

Body Type

  • Dynamic : 물리 엔진의 힘, 중력에 영향을 받는 오브젝트
  • Kinematic : 스크립트로 움직임을 직접제어
  • Static : 물리적으로 고정된 상태

방금 만든 Rigidbody2D 컴포넌트는
이미 Player 스크립트에서 중력을 다루기 때문에
Gravity Scale : 0

벽에 콜리전 추가

Wall에는 BoxCollider2D를 추가 해준다.

RigidBody도 추가하고 Kinematic

Dynamic으로 하면 부딪히면 벽이 움직인다.

Walls를 생성하고 Wall을 그룹화 시킨다.
이러면 Wall여러개를 동시에 컨트롤 하기 편해진다.


충돌 처리(Tag)

충돌 처리를 Player가 Wall 태그를 가진 오브젝트에 충돌하면 처리하는식으로 할거라
Wall에는 Wall 태그를 추가했다.

충돌 판정

//Player.cs

private void OnCollisionEnter2D(Collision2D collision)
{
    if(collision.gameObject.tag == "Wall")
    {
        Debug.Log("충돌!");
    }
}

프리팹(Prefabs)

프리팹이란

미리 만들어진 Object를 재활용 가능한 형태로 만들어 두는 것을 의미합니다.

Prefabs 폴더를 추가하고 아까 만든 Walls를 넣어준다.

이제 더블클릭해서 수정하면 Walls 프리팹 전체의 설정을 바꿀 수 있다.


벽을 코드로 관리하기

GameManager 오브젝트를 만들고 Game Manager 스크립트를 할당한다.
벽을 생성해주는 코드를 넣는다.

//GameManager.cs
using UnityEngine;

public class GameObject : MonoBehaviour
{
    public GameObject WallPrefab;
    public float SpawnTerm = 4;

    float spawnTimer;

    void Start()
    {
        spawnTimer = 0;
    }

    void Update()
    {
        spawnTimer += Time.deltaTime;

        if (spawnTimer > 0)
        {
            spawnTimer -= SpawnTerm;

            GameObject obj = Instantiate(WallPrefab);
   
            obj.transform.position = new Vector2(10, Random.Range(-2f, 2f));
        }

    }
}

public 선언한 WallPrefab에 GameManager 인스펙터에 프리팹으로 만들었던 Wall을 할당.

이러면 벽을 계속 생성만하고 삭제를 안한다.
플레이어가 GOSU면 렉이 걸리거나 다운될테니
화면 밖으로 나가면 벽을 삭제한다.

// Wall.cs
void Update()
{
    transform.Translate(Vector2.left * Time.deltaTime * Speed);
    if (transform.position.x <-10)
    {
        Destroy(gameObject);
    }
}

게임오버 판정 추가하기

벽에 닿았을때 뿐만 아니라 위 아래에 닿아도 게임 오버를 해야한다.
그래서 위 아래에 박스를 추가해서 Wall태그를 달면 닿았을때 죽을거다.



복사해서 위, 아래 총 2개 배치한다.


플레이어 애니메이션 추가

플레이어에 Animator 컴포넌트를 추가한다.

Animation 폴더도 만든다.
애니메이션 넣을 폴더임.

폴더안에 애니메이터 컨트롤러를 만든다.
이름은 PlayerAnimatorController

애니메이션을 수정할 수 있는 팝업을 연다.

  • Window > Animation > Animation

Hierarchy에서 Player를 선택한 상태에서 팝업에서 Create를 클릭한다.
애니메이션 이름은 Fly라고 했다.


점수 시스템

GameManager에서 점수를 관리한다.

// GameManager.cs
using UnityEngine;

public class GameManager : MonoBehaviour
{
    public GameObject WallPrefab;
    public float SpawnTerm = 4;

    float spawnTimer;
    private float score;    
    public float Score
    {
        get
        {
            return score;
        }
    }
    void Start()
    {
        spawnTimer = 0;
        score = 0;
    }

    {
        spawnTimer += Time.deltaTime;
        score += Time.deltaTime;

        if (spawnTimer > 0)
        {
            spawnTimer -= SpawnTerm;

            GameObject obj = Instantiate(WallPrefab);
            obj.transform.position = new Vector2(10, Random.Range(-2f, 2f));
        }
    }
}

점수를 표시할 UI오브젝트를 추가한다.


처음 추가하면 이상한 창이 뜰텐데 Import를 눌러주자

인스펙터를 이용해 적당한 위치에 두자
난 오른쪽 위에 두었다.

글자 정렬 버튼

GameManager의 점수를 텍스트로 가져와야한다.

// GameManager.cs
    public static GameManager Instance;
    private void Awake()
    {
        Instance = this;
    }

Awake

Awake는 Start보다 먼저 실행된다.

자세한 정보는
https://docs.unity3d.com/kr/2022.3/Manual/ExecutionOrder.html

Score에 스크립트를 추가한다.
이름은 DisplayScore.

//DisplayScore.cs
void Update()
{
	float score = GameManager.Instance.Score;
	GetComponent<TextMeshProUGUI>().text = ((int)score).ToString();
}


게임오버 구현

지금까지는 GameScene 씬에서 구현을 진행했다.
GameOverScene이라는 씬을 만들어서 게임오버 화면을 구성하고 게임오버시에 해당 씬으로 넘어가도록 구현할거다.

게임 오버 화면 생성하기


씬을 만들고 씬을 불러올 수 있도록 유니티에게 알려줘야한다.

  • 안알려주면 안불러와짐.


    순서도 중요하다.
    처음 나올 씬은 맨 위에 위치해야 한다.

GameOverScene으로 넘어자서
배경 이미지를 만들자.

원하는 색으로 설정했다.

Game Over 텍스트와 버튼들을 추가하고 배치했다.
(TextMeshPro로 만들었다)

버튼 구현하기

Play Again을 누르면 GameScene을 불러오고
Quit를 누르면 꺼지도록 구현한다.

GameOverManager 오브젝트를 생성하고 같은 이름의 스크립트를 할당해준다.

// GameOverManager.cs
using UnityEngine;
using UnityEngine.SceneManagement;

public class GameOverManager : MonoBehaviour
{
    void Start()
    {
        
    }

    void Update()
    {
        
    }
    
    public void OnTryAgainPressed()
    {
        SceneManager.LoadScene("GameScene");
    }

    public void OnQuitPressed()
    {
        Application.Quit();
    }
}

버튼 둘다 GameOverManager 오브젝트를 넣어주고 함수도 설정한다.

죽으면 점수를 표시해보자.
씬이 다르기 때문에 물리적으로 컴퓨터에 저장해서 불러오는 식으로 구현한다.

// Player.cs
private void OnCollisionEnter2D(Collision2D collision)
{
    if(collision.gameObject.tag == "Wall")
    {
        int score = (int)GameManager.Instance.Score;
        PlayerPrefs.SetInt("Score", score);
        //Debug.Log("충돌");
        SceneManager.LoadScene("GameOverScene");
    }
}

Player가 죽을때 저장하고

// GameOverManager.cs
public TextMeshProUGUI ScoreText;
void Start()
{
    int score = PlayerPrefs.GetInt("Score", 0);
    scoreText.text = score.ToString();
}

GameOverScene이 그려질 때 불러온다.

GameOverManager의 ScoreText에 점수 텍스트를 할당해주면

게임 오버시에 점수가 표시된다.


사운드 추가하기

https://jdwasabi.itch.io/8-bit-16-bit-sound-effects-pack
Balloon start riding 1
Balloon start riding 2


https://assetstore.unity.com/packages/audio/music/casual-jingles-022420-163758?aid=1011l5f3d&pubref=chrome

플레이어 사운드

플레이어가 소리를 낼거라 Player에 Audio Source 컴포넌트를 추가한다.

// Player.cs
public AudioClip UpSound;
public AudioClip DownSound;

void Update()
{
    if (Input.GetButtonDown("Jump"))
    {
        GetComponent<AudioSource>().PlayOneShot(UpSound);
    }
    if (Input.GetButtonUp("Jump"))
    {
        GetComponent<AudioSource>().PlayOneShot(DownSound);
    }
    if (Input.GetButton("Jump"))
    {
        v -= Accel * Time.deltaTime;
    }
    else
    {
        v += Gravity * Time.deltaTime;
    }
}


좀 많이 시끄럽다.

게임오버 사운드

게임오버 소리도 추가한다.
GameOverManager 오브젝트에도 Audio Source 컴포넌트를 추가해주고 소리도 설정한다.

BGM

마찬가지로 GameManager 오브젝트에 Audio Source 추가하고 노래를 넣고 Awake와 Loop를 활성화 해주면 무한반복 배경음이 완성!


빌드


경로 설정 해주고 빌드

완성!


수업 끝!

0개의 댓글