본문 바로가기

spartacodingclub/개발보고서

게임개발 종합반 3주차

https://spartacodingclub.kr/

 

*스파르타 클럽 강의[게임개발 종합반 7기] 3주차를 듣고 난 개인적인 후기*

더보기

이전 강의들보다는 확실히 오류도 적고 수월했던 주차 수업이었다

 

기본적인 게임 요소들에 대한 자세한 설명과

C# 실제 코드들을 학습할 수 있어서

이 수업을 다 듣고 나면 나만의 게임을 만들 수 있을 것 같다는 생각이 들었다

비전공자에게는 많이 힘들겠지만... 일단 강의를 잘 따라가서 끝내면

어느새 그럴듯한 게임이 만들어져 있는 걸 볼 수 있을 것이다

 

 

*실습*

 

1. 캐릭터가 적 밟아서 공격하기

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CharacterJump : MonoBehaviour
{
    public Rigidbody2D rigid;
    public float jumpHeight;

    public AudioSource audioSource;
    public AudioClip clip;

    int jumpCount = 0;
    int limitJumpCount = 1;

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.UpArrow))
        {
            if (jumpCount <= limitJumpCount)
            {
                jumpCount = jumpCount + 1;
                rigid.AddForce(Vector2.up * jumpHeight, ForceMode2D.Impulse);
            }
        }
    }
    private void OnTriggerEnter2D(Collider2D collision)
    {
        if(collision.gameObject.tag == "ground")
        {
            jumpCount = 0;
        }
        else if(collision.gameObject.tag == "enemy")
        {
            EnemySaurus enemy = collision.gameObject.GetComponent<EnemySaurus>();
            enemy.OnDamage();
            rigid.AddForce(Vector2.up * jumpHeight, ForceMode2D.Impulse);
            audioSource.volume = SoundManager.I.Volume;
            audioSource.clip = clip;
            audioSource.Play();
        }
    }
}

해당 코드를 실행해보면 캐릭터가 점프해서 적을 밟으면

캐릭터는 살짝 점프를 하고, 적은 살짝 점프한 뒤 떨어져죽게 된다

 

audio가 포함된 코드는 이후 소리 파트에서 설명하도록 하겠다

우선 태그가 enemy인 오브젝트와 캐릭터의 발 부분에 지정한 'Box Collider 2D'와 충돌하면

EnemySaurus enemy = collision.gameObject.GetComponent<EnemySaurus>();
            enemy.OnDamage();
            rigid.AddForce(Vector2.up * jumpHeight, ForceMode2D.Impulse);

 

이 세 줄의 코드를 진행하게 만든다

우선 적 오브젝트에 만든 스크립트인 [EnemySaurus]를 불러오는 코드를 작성하고

그 스크립트 안에서 OnDamage라는 함수를 불러온다

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnemySaurus : MonoBehaviour
{

    public Rigidbody2D rigid;
    public SpriteRenderer reneder;
    public float moveSpeed;
    bool isLeft = true;
    bool isDead = false;

    // Update is called once per frame
    void Update()
    {
        if (isDead)
        {
            return;
        }

        if (isLeft)
        {
            rigid.velocity = Vector2.left * moveSpeed;
            reneder.flipX = false;
        }
        else
        {
            rigid.velocity = Vector2.right * moveSpeed;
            reneder.flipX = true;
        }
    }

    public void OnDamage()
    {
        BoxCollider2D col = gameObject.GetComponent<BoxCollider2D>();
        col.enabled = false;
        reneder.color = new Color(1, 1, 1, 0.5f);
        rigid.AddForce(Vector2.up * 8, ForceMode2D.Impulse);
        isDead = true;
    }

    private void OnCollisionEnter2D(Collision2D collision)
    {
        if(collision.gameObject.tag == "wall")
        {
            isLeft = !isLeft;
        }
    }

}

 

이전 포스터에서 추가한 내용을 제외하고 OnDamage() 부분만 보자면

예전에 캐릭터 스크립트에서 적과 부딪히면 죽는 효과를 내줬던 코드를 그대로 가지고 와준다

여기에서 isDead는 죽었는지 안 죽었는지를 확인하고 죽었을 때 바닥 아래로 떨어져 죽을 수 있도록 한다

 

 

2. 게임 매니저/싱글톤을 이용한 게임오버/게임승리

싱글톤이란?

게임 내/씬 내에 단 하나만 존재하는 클래스를 의미한다

일반적으로는 룰을 관리하는 매니저 관련 클래스에서 주로 사용한다

게임 매니저/사운드 매니저 등 나누어 사용하는데

현재 게임오버 및 게임승리에는 게임 매니저를 만들어 사용해보려고 한다

 

우선 GameManager를 만들어 스크립트를 열어 준 뒤 아래의 코드를 입력해준다

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class GameManager : MonoBehaviour
{
    public static GameManager I;
    public int Score;

    private void Awake()
    {
        I = this;
    }

    public void GameOver()
    {
        Invoke("GameOver_", 2);
    }

    public void WinGame()
    {
        GameOver_();
    }


    public void AddScore(int score)
    {
        Score = Score + score;
        Debug.Log(Score.ToString());
    }

    void GameOver_()
    {
        SceneManager.LoadScene(0);
    }
}

해당 코드에서는 설명할 것이 많긴 하지만

그냥 간단하게 설명하자면 이 클래스를 다른 다양한 스크립트에서 편하고 쉽게 사용할 수 있게

자기 자신을 I와 같은 간단한 변수명으로 선언한다고 보면 된다(Awake 함수)

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CharacterDamage : MonoBehaviour
{
    public BoxCollider2D col1;
    public BoxCollider2D col2;
    public SpriteRenderer render;


    
    void OnDamage()
    {
        col1.enabled = false;
        col2.enabled = false;
        render.color = new Color(1, 1, 1, 0.5f);
        GameManager.I.GameOver();
    }
    
    private void OnCollisionEnter2D(Collision2D collision)
    {
        if(collision.gameObject.tag == "enemy")
        {
            OnDamage();
        }
    }
}

이 클래스 안에 있는 게임 오버 함수를 캐릭터가 죽었을 때 실행한다고 치면

위와 같이 코드를 선언해주면 적에게 부딪혔을 때 끝도 없이 바닥으로 떨어지는 캐릭터가

2분이 지나자마자 다시 처음 화면으로 돌아가는 걸 볼 수 있다

 

위와 동일하게 게임승리 또한 다시 게임을 시작하는 거라고 친다면

(아직 게임 승리를 알리는 알림창이라든가 그런 거를 사용하지 못한다고 가정했을 때)

 

게임승리 코드가 나올 수 있는 조건을 만들어줘야 한다

이 수업에서는 깃발이라는 오브젝트를 추가해서

캐릭터가 깃발에 닿았을 때 게임승리 함수를 가져오는 코드를 사용했다

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Goal : MonoBehaviour
{
    // Start is called before the first frame update
    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.gameObject.tag == "Player")
        {
            GameManager.I.WinGame();
        }
    }
}

 

 

 

3. BGM/효과음 추가 및 사운드 매니저

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SoundManager : MonoBehaviour
{
    public static SoundManager I;

    public float Volume;

    private void Awake()
    {
        I = this;
    }

}

위의 사운드 매니저를 게임 매니저 추가한 것처럼 추가한 뒤

이전 점프 함수에서 사용했던 audio 변수들을 이번에 사용해보면 된다

 

게임에 사운드를 내기 위해서는 스피커를 달아줘야 되는데

추가하기를 눌러서 위의 component를 추가하면 된다

 

audioclip에는 당연히 프로젝트에 [music] 폴더를 만들어

그 안에 게임 안에 넣고 싶은 효과음 및 bgm을 넣어두고

audioclip에 소리를 내고 싶은 음악을 끌어놓으면 된다

여기에서 play on awake는 게임이 시작되면 이 노래를 재생할것인지 물어보는 것이고

loop는 이 노래를 반복적으로 행할것인지 물어보는 것이다

배경노래는 당연히 두 부분에 다 체크해줘야 한다

 

그리고 점프에 뜨는 source에는 캐릭터를 그대로 끌어놓고

clip에는 노래파일을 끌어놓으면 된다

 

이렇게 되면 캐릭터가 점프해 적을 밟아 죽였을 때 효과음 소리가 난다는 걸 알 수 있다

 

배경음악을 넣고 싶다면 위와 같은 것을 Hierarchy에 만들어서

 

add component에서 audio source를 추가한 뒤

그곳에 배경음악을 끌어놓고 반복 재생 및 최초 실행 시 재생에 체크하면 된다

 

 

 

4. 점수 추가

 

이 수업 실습에서는 게임 오브젝트인 코인을 먹었을 때 점수를 얻을 수 있는 구조를 만들어준다

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Coin : MonoBehaviour
{
    public int Score;

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.gameObject.tag == "Player")
        {
            GameManager.I.AddScore(Score);
            Destroy(gameObject);
        }
    }
}

아직 점수를 올려주는 오브젝트를 만들 수 없으니

코인 오브젝트 내에서 coin이라는 스크립트를 새로만든다

우선 게임매니저 안에 만들어놓은 스코어에 점수를 누적해준다

그리고 캐릭터와 부딪힌 코인은 화면에서 사라지도록 조작한다

 

그러면 화면과 같은 코인 스크립트가 화면에 나타난 여러 개의 코인에 부여되는 것을 볼 수 있다

각 코인에 점수를 각자 다르게 설정이 가능해서

코인의 크기를 키워 더 많은 점수를 주게 만들 수도 있다

 

아까 전 게임 매니저 안에 있던 score 함수를 잘 보면

debug.log를 이용해서 점수를 터미널에 띄워주는 것을 볼 수있다

이는 아직 게임 내에 점수를 표시해주는 오브젝트를 넣지 못하기 때문에

점수 체제가 정확하게 잘 적용되고 있는지 확인하기 위해 넣은 코드이다