프로젝트/[Sparta] 유니티로 만드는 게임개발 종합반

[4주차 게임] 르탄이 카드 뒤집기 게임 -1

순정법사 2022.12.22

A. 기본 씬 구성하기

1. 프로젝트 생성 및 설정하기

a. 프로젝트 생성하기 

2D / findRtan 프로젝트 생성

 

안뇨옹

 

b. 기본 세팅하기

1) windows → 2x3 layout

2) free aspect → phone 클릭!

3) SampleScene → MainScene으로 rename

4) MainCamera : rgb → 90, 90, 225

 

이번에도 이미지 사이즈가 큰데, 이미지 사이즈를 조절할거라 카메라 사이즈는 조절하지 않음

 

눈아픈 배경색

 

 

2. 타이머 생성 및 설정하기

a. 타이머 생성

Hierarchy / Text(UI/Legacy)

* name: timeTxt

 

b. 타이머 기본설정

reset후 진행

 

* PosY : 400

* width: 200, height: 200

* font size: 70

* 가운데 정렬 / Bold

* color : 255, 255, 255

 

c. 타이머 움직이기

1) gameManager 만들기

 

(a) Script 폴더 -> gameManager.cs 생성

(b) gameManager(Create Empty) 객체 생성

(c) 연결

 

2) 시간이 가게 하기

 

(a) 위에서 만든 타이머를 연결하고

(b) 함수를 생성해서 소숫점 둘째자리까지 시간을 표현하기

 

using UnityEngine.UI;

...

public Text timeTxt;
float time = 0.0f;

void Update()
{
    time += Time.deltaTime;
    timeTxt.text = time.ToString("N2");
}

 

3) 확인하기

 

 

 

3. 르탄이 이미지 받아두기

a. 르탄이 이미지 모음

1) Images 폴더 만들고 안에 넣기

 

https://s3.ap-northeast-2.amazonaws.com/materials.spartacodingclub.kr/game_new/week04/rtan.zip

 

2) 이미지 크기 수정

 

(a) 이미지 클릭

(b) Inspector / pixels per unit: 450

(shift 눌러서 한번에 잡아 다른 르탄이들도 모두 450으로)

 

 

+ 이미지 크기 수정하는 방법에는 카메라 사이즈를 조절하는 방법도 있음

 

 

 

B. 카드 생성하기

1. 카드의 기본 구성

기본적으로 Cards라는 Empty 객체 안에 16개의 card가 들어있는 형태로 구성할 예정

 

 

2. 카드 한 장 만들기

a. 카드 만들기

1) Cards(Create Empty) → card(Create Empty) 한 장만 생성

 

* card / scale : 1.3, 1.3

 

2) card 아래에 sprite/square로 front/back 두개 생성

 

* 앞면(front): 르탄이 이미지

* 뒷면(back) : ? 물음표

 

3) front에 rtan0 이미지 끌어다 놓기

 

다 설정되었으면 front를 InActive (back을 만들어야 하기 때문)

 

4) back 아래에 Canvas 생성

 

?라는 텍스트(text객체)가 들어가야 하기 때문에 Canvas가 필요하고,

그 Canvas를 World Render로 해줘야 함

 

* Render-Mode : World Space

* Rect Transform reset

* Order in layer : 1

 

 

5) Canvas 아래에 Text생성

 

* width / height : 100, 100

* Scale : 0.01 , 0.01

* text : ? 

* Font Size: 50

* 가운데정렬 / Bold 

 

 

 

C. 카드 배치하기

1. 배치전략 알기

GameManager에서 복사하기 

→ 현재 카드 사이즈가 x:1.3, y:1.3 이니까, 1.4 만큼씩 띄워서 붙이기

 

 

 

2. 카드 생성 및 위치 잡기

a. 카드 자동 생성하기

1) card를 프리팹으로 만들기

 

card는 삭제, Cards는 유지

### Warning!

[문제]

 

Cards를 Prefabs 화 시켜서 제거하고 card로 재등록 하려니까 나온 이슈

[해결]

프리팹의 패킹관계를 없애야 한다


[출처]

https://docs.unity3d.com/kr/2022.2/Manual/UnpackingPrefabInstances.html

 

2) 카드 복제 코드 생성하기

 

gameManager에서 진행

 

(a) card를 새로 만들어서 cards 아래에 붙이기

 

Instantiate를 아래와 코드와 받으면 생성된 오브젝트를 제어할 수 있음 = 변수 제어와 같음 

 

public GameObject card;

void Start()
{
    for (int i = 0; i < 16; i++)
    {
        GameObject newCard = Instantiate(card);	//(a)
        newCard.transform.parent = GameObject.Find("Cards").transform;
    }
}

 

Find()의 객체가 이름이 동일하지 않으면 이런 오류가 생김 (대소문자 구분)

 

b. 카드 위치 구성하기

0) 전략을 생각하기

 

참고로 0번째 부터 시작하니, 1번째는 사실상 두 번째 카드

 

[예를 들어 1번째 라고 하면]

x : 1을 4로 나눈 몫 = 0

y : 1을 4로 나눈 나머지 = 1

0,1 위치 ⇒ 1.4씩 곱해주면 ⇒ 0, 1.4

 

[예를 들어 7번째 라고 하면]

x : 7을 4로 나눈 몫 = 1

y : 7을 4로 나눈 나머지 = 3

(1,3) 위치 ⇒ 1.4씩 곱해주면 ⇒ (1.4, 4.2) 위치

 

1)  카드 위치 잡아주기

 

void Start()
{
    for (int i = 0; i < 16; i++)
    {
        GameObject newCard = Instantiate(card);
        newCard.transform.parent = GameObject.Find("Cards").transform;

        float x = (i / 4) * 1.4f;
        float y = (i % 4) * 1.4f;
        newCard.transform.position = new Vector3(x, y, 0);
    }
}

 

이렇게 하면 첫번째 카드를 중심으로 하기 때문에 중심을 맞춰야 함

 

2) 카드를 전체적으로 옮겨주기

 

x, y를 적당히 빼줘서 전체를 가운데에 위치하게 하기

x: -2.1f  y: -3.0f

 

void Start()
{
    for (int i = 0; i < 16; i++)
    {
        GameObject newCard = Instantiate(card);
        newCard.transform.parent = GameObject.Find("cards").transform;

        float x = (i / 4) * 1.4f - 2.1f;
        float y = (i % 4) * 1.4f - 3.0f;
        newCard.transform.position = new Vector3(x, y, 0);
    }
}

 

3) 확인하기

 

잘 나왔당!

 

 

 

E. 카드 랜덤섞기

1. 랜덤 섞기 전략

C#에서 리스트 요소들을 랜덤하게 섞는 방법

 

  1. [0, 0, 1, 1, 2, 2, ..., 7, 7] 까지 쓰인 리스트를 만들고
  2. 이걸 섞어서 [2, 3, 4, 1, 2, 0, 1, ..., 7]로 만들고
  3. 카드가 만들어 질 때 하나씩 꺼내서 르탄이 이미지를 붙여주기

 

 

2. 리스트를 랜덤으로 섞기

a. 리스트 생성하기

int[] rtans = { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7 };

 

b. 리스트 섞기

using System.Linq;

...

void Start()
{
		int[] rtans = { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7 };

    rtans = rtans.OrderBy(item => Random.Range(-1.0f, 1.0f)).ToArray();	// 1)

    for (int i = 0; i < 16; i++)
    {
        GameObject newCard = Instantiate(card);
        newCard.transform.parent = GameObject.Find("cards").transform;

        float x = (i / 4) * 1.4f - 2.1f;
        float y = (i % 4) * 1.4f - 3.0f;
        newCard.transform.position = new Vector3(x, y, 0);

        Debug.Log(rtans[i]);
    }
}

 

1) 리스트를 랜덤하게 정렬하고 배열로 만듦

 

만약 rtans.OrderBy(item => item).toArray(); 로 코드가 되어있다면,

위 rtans 배열에 -1이 있다고 치고,

-1이 배열의 어디에 있든 오름차순으로 정렬되어서 가장 먼저 나옴! 

 

콘솔에 나온 모습

 

 

3. 르탄이 붙여주기

a.  Resources 폴더에 옮겨두기

어떤 이미지나 파일을 코드로 지정하고 싶을 때는 Resources 폴더에 생성 후 옮기기

 

그냥 Images -> Resources로 이름만 변경함

 

b. 르탄이 붙이기

void Start()
{
    int[] rtans = { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7 };

    rtans = rtans.OrderBy(item => Random.Range(-1.0f, 1.0f)).ToArray();

    for (int i = 0; i < 16; i++)
    {
        GameObject newCard = Instantiate(card);
        newCard.transform.parent = GameObject.Find("cards").transform;

        float x = (i / 4) * 1.4f - 2.1f;
        float y = (i % 4) * 1.4f - 3.0f;
        newCard.transform.position = new Vector3(x, y, 0); 	

        string rtanName = "rtan" + rtans[i].ToString();	// 1)
        newCard.transform.Find("front").GetComponent<SpriteRenderer>().sprite // 2)
        	= Resources.Load<Sprite>(rtanName);	//3)
    }
}

 

1) 르탄이 이름(이미지 이름)을  위에서 섞은 랜덤 배열을 기반으로 만들기

 

2) 새 카드 아래에 front 를 찾아서, sprite를 변경

 

3) Resources 폴더에 있는 rtanName 이미지를 가져옴

 

c. 확인하기

프리팹에서 front를 켜고, back을 끈 다음 확인

 

잘 나온당!

 

확인을 다 했으면 다시 front를 꺼주장 

 

 

 

F. 애니메이션

1. 카드 기본 애니메이션

a. 기본 애니메이션(card_idle) 만들기

1) Animations 폴더 안에 card_idle 만들기

 

프리팹에있는 card에 붙이기

Loop Time 체크

 

2) 프리팹에있는 카드를 Hierarchy에 꺼내기

 

card_idle을 더블클릭하고 프리팹에 있는 카드를 클릭해서는 애니메이션 창이 활성화 되지 않음

그래서 왼쪽의 Hierarchy 탭에 프리팹을 끌어다 놓으면 됨!

 

3) 애니메이션 레코딩하기

 

0:20 에만 rotation z:3 

 

b. 확인하기

 

띠요오옹

 

 

2. 카드 클릭 애니메이션

a. 뒤집기 애니메이션(card_flip) 만들기

1) Animations 폴더 안에 card_flip 만들기

 

Hierarchy의 card에 붙여놓기 (아무 일도 일어나지 않음)

 

2) card_flip 더블클릭 후 card를 클릭하면 애니메이션이 idle로 활성화되는데, 이걸 flip으로 변경

 

3) 애니메이션 만들기

 

0:10 부분만 Scale 을 x:1.2, y:1.2 

살짝 눌린 것같은 느낌

 

바운스 바운스 두근대~

 

 

3. 애니메이션 조건 만들기

a. idle 와 flip 의 상관관계

0) Animation의 card controller를 더블클릭해서 Animator창 활성화

 

1) Animator 를 열고, transition 만들기

 

* 오른쪽 클릭하고 make transition 해서 생성

* 오는 것 / 가는 것 두 개 생성함

* (transition 설정) 바로바로 실행되어야 하기 때문에 has exit time 체크 해제, transition duration 0

 

 

2) 파라미터 만들기

 

bool 형식(true / false)의 isOpen

 

3) transition에 파라미터 조건 붙이기

 

* Conditions에서 추가 버튼을 눌러서 생성

 

flip ⇒ idle : bool이 false 가 되면 발동

idle ⇒ flip : bool이 true 가 되면 발동

 

4) 기존 Prefabs에 있는 카드 프리펩 삭제 후 재 등록 후 객체삭제

 

5) gameManager에서 제거되어있는 card 다시 연결

 

 

4. 카드 클릭하면 뒤집어지기

a. card.cs 생성하고 프리팹에 연결

 

b. 카드에 button 속성 붙이기

 

c. 클릭하면 뒤집히게 하기

card.cs에서 진행

 

1) 에니메이션을 연결하기

2) 클릭하면 active inactive되게 하기

 

public Animator anim;	//1) 

public void openCard()
{
    anim.SetBool("isOpen", true);
    transform.Find("front").gameObject.SetActive(true);	//2)
    transform.Find("back").gameObject.SetActive(false);
}

 

d. 1) Anim 연결하기 

anim은 이렇게 연결하면 됨

 

 

e. 2) 함수 연결하기

 

d. 확인하기

촵촵촵!