나 개발자 진짜 되냐?

모바일 게임 만들어보기 1 - 3 소나기 맞기 게임 본문

유니티를 공부해봐요!

모바일 게임 만들어보기 1 - 3 소나기 맞기 게임

Snow Rabbit 2024. 9. 12. 00:31

자! 

지금까지 우리는 

캐릭터가 움직이고

마우스 클릭으로 왔다 갔다 거리는 거 까지 해보았다

 

지금부터 물방울을 만들어 보도록 하자!!

 

이 물방울의 특징은

 

1. 위에서 랜덤하게 떨어진다

2. 크기가 3종류이다.

3. 크기에 따라 점수가 다르다.

 

 

 

자 먼저 물방울을 하나 만들어보자!!

 

Hierarchy > 2D Object > Sprites > Circle

 

원하나 만들어 준다!

 

그다음에 우리는 이 친구를

Rain으로 저장한다!

 

그리고 우리는 이 친구를

Position : 0 4 0

Color : 150 150 200

로 바꿔주시면

 

귀여운 물방울이 하나 생깁니다!

우리는 이 물방울에게 중력을 부여해줘야 합니다.

 

 

 

보면 밑에 Add Component가 있다.

이것을 눌러주고!

 

Rigidbody 2D를 눌러서 등록해 준다.

이 

Rigidbody는 물리적인 힘을 적용시킬 수 있다. 👊

마찰력, 중력, 물체 무게 값 조절 등등 

 

 

이렇게 해주면 물이 위에서 아래로 떨어지게 된다!

 

 

오 이제

우리는 충돌현상을 구현해야 하는데

 

왜?

( 물과 캐릭터 충돌현상으로 물방울을 먹어 점수를 얻고,

물이 바닥에 닿을 때는 점수가 생기면 안 되기 때문! )

 

충돌현상을 만들려면

 

충돌이라는 뜻의

새로운 친구가 필요하다!

 

또 Add Component > Circle Collider 2D를 눌러준다,

 

이 콜라이더라는 친구 덕분에!

 

우리는 충돌하고 멈출 수 있게 된다.

 

이 친구가 없다면 바람처럼 스르륵 하고 사라질 것이다. 

 

 

 

충돌이라는 것은

 

하나가 아니라

둘이 같이 부딪혀야 한다.

그렇기 때문에

우리는 물뿐만 아니라

바닥에도 충돌을 만들어줘야 한다.

 

아까처럼 Add Component에서

이번에는 네모모양이기 때문에

Box collider 2D를 추가해 준다.

 

이렇게 해주면!

 

 

 

물방울이 바닥에 닿게 된다.

 

 

위에서 봤듯

우리는 바닥에 물방울이 닿았지만,

이렇게 여러 개 쌓이면 지저분해 보이기 때문에

바닥에 닿은 건 사라지게 해야 한다!

 

바닥에 사라지게 하기 위해선 코딩해줘야 하는데

 

우리가 저번에 만들어준 Scripts에서

( Project > Assets 안에 )

Create > C#을 해준다.

 

그리고 Rain라고 이름을 정해준다.

 

스크립트에 들어와서

 

우리는 

OnCollisionEnter2D

 

라고 쳐주면

바로 이 친구가 자동으로 나오게 된다.

 

 

우리는 이제 Collision 관련 코드는

여기에 적을 것이다.

 

해석을 해보자면

 

On = 어떤 이벤트, 현상이 발생될 때 사용

Collision = 충돌

Enter = 들어가다. 시작되는 순간! 

( 여기서는 충돌이 시작되는 순간 )

2D = 말 그대로 2D

 

( Collision2 D collision )

대문자 C를 우리는 변수 소문자 c로 부르기로 한다.

 

 

라는 뜻이다!

 

 

자자!

우리는 바닥에 부딪혔을 때를 써야 하기 때문에

 

조건문을 써서 

만약에! 바닥에 부딪힌다면?

을 써줘야 한다

 

 

collision은 아까 위에서 

변수 선언을 했기 때문에 

Collision2D의 정보가 다 들어가 있다.

 

gameObject의 name이름이 Ground 라면이라는 뜻이 된다.

 

하지만 이 Ground의 이름이 바뀐다면

이 친구는 동작을 안 할 것 아닌가!!

 

그래서 우리는 고유의 Tag를 달아줘야 한다.

 

Tag는

Hierarchy > Ground

> Inspector 바로 밑에 Tag가 있다.

 

 

 

여기 Tag를 눌러보면 add Tag가 있다.

오른쪽에 + 눌러줘서 우리는

Ground라고 태그이름을 정하고 Save 해준다.

 

다음에 다시 Ground 프로젝트를 눌러서

Inspector 간 다음 Tag를 눌러보면

우리가 방금 만든 친구

 

Ground가 보인다.

 

태그를 설정해 주었으면

우리는 코드도 수정해줘야 한다!

 


아까는 name이었지만

지금은 Tag를 쓰기 때문에

 

CompareTag 태그를 비교해 준다 

"Ground" 태그면 if 조건문 수행한다! 

라는 의미가 된다!!

 

 

자 이제 태그를 달았으니

 

Destory라는 함수를 써서 우리는 물방울을 뿅 하고 사라지게 할 텐데!

 

 

이 함수는 

매애애앤 위에

MonoBehaviour

 

이 친구 덕분에

Destory를 사용할 수 있다.

 

 

 

this는

자기 자신이라는 뜻으로

 

여기서 자기 자신은 Rain 물방울 이기 때문에

물방울이 파괴된다고 해석할 수 있다.

 

그러면 우리는 이제

 

 private void OnCollisionEnter2D(Collision2D collision)
 {
     if (collision.gameObject.CompareTag("Ground")) // 태그를 달아준 곳에서 만 동작하도록 실행한다.
     {
         Destroy(this.gameObject);
     }
 }

 

까지 했다!

 

저와 같은가요?!

 

그럼 다행입니다!!

 

 

자 그러면 우리는 이제 물방울을

랜덤 한 곳에서 떨어뜨려야 한다.

 

일단 물방울을 랜덤 한 곳에서 떨어뜨리려면

높은 y값에서 x 값을 조절해주어야 한다.

 

재어보니

x는 -2.4에서 2.4 정도

y는 3에서 5 정도

된다.

 

이 친구들을 어떻게 랜덤 하게 둘 수 있을까?!

 

코드를 같이 보자!

 

/* 값 추출하기 */
 float x = Random.Range(-2.4f, 2.4f); // x값 범위를 적고, 변수 x를 생성한다.
 float y = Random.Range(3f, 5f); // y값 범위를 적고, 변수 y를 생성한다.

 /* 추출값을 벡터에 넣어주기*/
 transform.position = new Vector3(x, y, 0);

 

자 먼저 랜덤하게 둘 범위를 정해놓고

그 사이에서 나온 값을 x에 저장하는 식으로 짰다.

 

Random.Range는

랜덤 한 범위라는 뜻이다.

 

() 괄호 안에 있는 것은

최솟값, 최댓값이다.

 

방금 생긴 변수들은

 

position에 위치하고 있기 때문에

전에 썼던 transform.position을 사용해야 한다.

 

벡터값에 x, y을 넣어준다.

 

이렇게 해주면

랜덤 한 위치에 물방울이 생긴다.

 

 

 

이제 우리는

물방울의 크기 또한 랜덤으로 생성해주어야 한다.

또 그 크기에 따라 점수도 차등해야 한다.

 

우리는 물방울을 3종류로 나누어

가장 큰 물방울은 가장 높은 점수를,

가장 작은 물방울은 가장 낮은 점수를

주도록 설정해보려고 한다!

 

먼저

 

위에처럼 변수를 하나 만들어주어야 한다.

그 변수가 변할 때마다, 우리는 랜덤 하게 값이 나오게 하기 위해서이다.

 

위에서 물방울 위치는 소수점이기 때문에 float를 쓰며,

물방울은 3개가 전부니까 정수형인 int를 써준다.

 

 

엇 123 총 세 개인데 왜 숫자는 4까지 인가요?

싶으실 텐데

그 이유는 최댓값은 그전 숫자까지만 포함된다.

 

그래서 123 세 개를 쓰려면

1부터 4까지라고 해야

1,2,3 이렇게 세 종류가 나오게 된다.

 

실수의 경우

값이 만약에 2.7이어도 그 전은 2.6999가 되기 때문에

2.7f 그대로 써도 값이 변하지 않지만

정수는 숫자 하나로 크게 갈리기 때문에

 

정수형 최댓값 헷갈리지 말자!

자 이제

type를 랜덤 하게 했으니

1이 나왔을 때 2가 나왔을때 3이 나왔을때

각각 정해주어야 한다 

 

조건문 if를 쓴다.

 

 

이렇게 3종류를 써준다.

 

if를 세 번 쓰면 안 되나요?!

 

네!

 

예를 들어보자

type값이 1이다.

if값이 만약에 맞다면

그 밑에 2,3은 볼 필요가 없다.

else는 그럴 경우 다 넘긴다.

 

하지만 만약에

셋다 if 문을 쓰게 되면

1이 맞고 2,3은 틀린데도

2도 검사하고 3도 검사한다.

 

그러면 생각보다 컴퓨터는 불필요한 일을 하기 때문에 

else if를 써주면서 

안 해도 되는 일을 만들어주지 않게 하는 것이다!

 

이렇게 만들어주었으면

우리는

사이즈도 각각

점수도 각각

만들어주어야 한다.

 

사이즈와 점수는 

따로 변수를 선언해주어야 한다.

 

class

바로 밑에다가 변수를 선언해 준다.

 

Start안에 넣으면 start안에서만 움직이는 변수가 되기 때문에

가장 넓은 부분에 쓰는 것이 다방면으로 쓰기 좋다.

 

size는 float로

score는 int로 선언한다.

 

 

 

사이즈의 경우

 

 

여기에 위치하기 때문에

 

우리는 또

transform.localScale = new Vector3( size, size, 0 );

 

을 

else if 끝나는

마지막줄에 적어주어야 한다.

 

 

마지막으로 색깔이다!

 

색의 경우,

 

 

Sprite Renderer에 있기 때문에!

 

저번에 했듯이!

 

우리는 Renderer을 따로 선언해주어야 한다.

 

저번이 기억 안 난다고요?

 

https://qua28.tistory.com/95

 

모바일 게임 만들어보기 1 - 2 소나기 맞기 게임

지난 시간에는캐릭터가 바닥에 서있는 장면 그리고 왔다 갔다 발이 움직이는 것까지해보았다.  이제 코드를 작성해야 한다..!! 코드는 Assets에서 Create > C# Scripts를 해준다. 이름은 Rtan으로 해

qua28.tistory.com

 

 

먼저 class 밑에

 

SpriteRenderer renderer;

 

해주고,

 

Start 와서

 

randerer = GetComponent<SpriteRanderer>();

 

를 해주면 선언 끝!

 

우리는 색상까지 입력할 수 있다!!

 

if문으로 가서

 

renderer.color = new Color();

renderer안에 color을 가져올 건데

그 값은 우리가 지금 새롭게 만들 거야!

new!!

 

Color ( 대문자 주의! )

하고 숫자를 넣어준다.

 

 

이렇게 쓰면 된다.

 

혹시 지금까지 내용을 잘 따라왔는지 보려면?!

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

public class Rain : MonoBehaviour
{
    /* 기본적인 사이즈와 스코어 변수선언 */
    float size = 1.0f;
    int score = 1;

    SpriteRenderer renderer; // 이친구는 변수를 선언해서 만들어줘야한다.

    // Start is called before the first frame update
    void Start()
    {
        renderer = GetComponent<SpriteRenderer>();

        
        /* 값 추출하기 */
        float x = Random.Range(-2.4f, 2.4f); // x값 범위를 적고, 변수 x를 생성한다.
        float y = Random.Range(3f, 5f); // y값 범위를 적고, 변수 y를 생성한다.

        /* 추출값을 벡터에 넣어주기*/
        transform.position = new Vector3(x, y, 0);

        int type = Random.Range(1, 4); //여기는 type1,2,3인 정수이기 때문에 int를 사용한다.
                                       //4라고 쓴 이유는 최댓값은 숫자 -1값까지만 범위에 포함된다. 1,3 으로 쓰면 1,2 만되기때문에
                                       //1,4 라고 써야지만 1,2,3이 된다.

        if (type == 1)
        {   
            size = 0.8f;
            score = 1;
            renderer.color = new Color(100/255f, 100/255f, 1f, 1f);
            //색은 f 값으로 들어가고 최댓값으로 나누어주어야한다.
            //유니티에서는 150을 하드코딩했지만, 여기서는 255로 나누어줘야한다.
        }
        else if (type == 2) // else if를 해주지 않고 다 따로따로 if문을 만들면 별개기 때문에 하나씩 다 검사하게 된다.
        {
            size = 1.0f;
            score = 2;
            renderer.color = new Color(130 / 255f, 130 / 255f, 1f, 1f);
        } 
        else if (type == 3) 
        {
            size = 1.2f;
            score = 3;
            renderer.color = new Color(150 / 255f, 150 / 255f, 1f, 1f);
        }

        /* 이 사이즈가 로컬스케일에 들어간다. */
        transform.localScale = new Vector3(size, size, size);
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    private void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject.CompareTag("Ground")) // 태그를 달아준 곳에서 만 동작하도록 실행한다.
        {
            Destroy(this.gameObject);
        }
    }
}

 

 

이 코드와 비교해 보세요!!

 

 

< 이 프로젝트는 스파르타 코딩수업에서 배운 내용을 복습 한 내용입니다. >