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

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

순정법사 2022.12.22

H. 카드 매칭하기

1. 카드 매칭 전략

  • 이름이 서로 일치하면 ⇒ (1초 후에) 카드를 둘 다 없애주기
  • 아니면 ⇒ (1초 후에) 두 카드를 다시 뒤집어주기

 

 

2. 카드 매칭하기

a. gameManager 싱글톤화

public static gameManager I;

void Awake()
{
    I = this;
}

 

b. 카드이름 저장하기

gameManager.cs에서 진행

 

public GameObject firstCard;
public GameObject secondCard;

 

c. openCard하면 firstCard 또는 secondCard에 나를 넣기

card.cs에서 진행 

 

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

    if (gameManager.I.firstCard == null)
    {
        gameManager.I.firstCard = gameObject;
    }
    else
    {
        gameManager.I.secondCard = gameObject;
        gameManager.I.isMatched();
    }
}

 

d. 카드 이름을 저장하고 비교하는 isMatched() 만들기

gameManager.cs에서 진행

 

1) front 를 찾아서 카드 이미지 이름을 받아오기

2) 다 끝났으면 다시 비워주기

 

public void isMatched()
{
    string firstCardImage = firstCard.transform.Find("front").GetComponent<SpriteRenderer>().sprite.name;	//1)
    string secondCardImage = secondCard.transform.Find("front").GetComponent<SpriteRenderer>().sprite.name;

    if (firstCardImage == secondCardImage)
    {
        Debug.Log("같다!");
    }
    else
    {
        Debug.Log("같지 않다!");
    }

    firstCard = null;	// 2)
    secondCard = null;
}

 

e. card 행동 준비하기

card.cs 에서 진행

 

1) 없애기, 뒤집어주기 함수 만들어두기

2) 같으면 → 1초 후에 둘 다 없애기 / 다르면 → 1초 후에 둘 다 뒤집어주기

3) 1초 후에 실행해야하니까, invoke를 따로 만들기

 

public void destroyCard()
{
    Invoke("destroyCardInvoke", 0.5f);
}

void destroyCardInvoke()
{
    Destroy(gameObject);
}

public void closeCard()
{
    Invoke("closeCardInvoke", 0.5f);
}

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

 

f. 같을 때 / 같지 않을 때 적절한 함수 불러주기

gamemanger.cs에서 진행 

 

1) firstCard에 붙어있는 card.cs 에서 destoryCard 를 부르기

public void isMatched()
{
    string firstCardImage = firstCard.transform.Find("front").GetComponent<SpriteRenderer>().sprite.name;
    string secondCardImage = secondCard.transform.Find("front").GetComponent<SpriteRenderer>().sprite.name;

    if (firstCardImage == secondCardImage)
    {
        firstCard.GetComponent<card>().destroyCard();	//1)
        secondCard.GetComponent<card>().destroyCard();
    }
    else
    {
        firstCard.GetComponent<card>().closeCard();
        secondCard.GetComponent<card>().closeCard();
    }

    firstCard = null;
    secondCard = null;
}

 

g. 확인하기 

 

어렵다...

 

 

I. 게임 끝내기

1. 카드가 모두 없어지면 게임 끝내기

a. 끝! 텍스트를 미리 만들어두기

TimeTxt 를 ctrl+d

 

* name : endTxt

* font size 200

* width: 300, height: 300, posY: 0

* color : 220 , 255, 0, 255

 

후 InActive

 

b.  매칭 됐을 때 남은 카드를 체크하기

gameManager.cs 에서 진행

 

1) cards를 찾아서, 아래에 몇 개의 자식이 있는지를 판단하기

 

public void isMatched()
{
    string firstCardImage = firstCard.transform.Find("front").GetComponent<SpriteRenderer>().sprite.name;
    string secondCardImage = secondCard.transform.Find("front").GetComponent<SpriteRenderer>().sprite.name;

    if (firstCardImage == secondCardImage)
    {
        firstCard.GetComponent<card>().destroyCard();
        secondCard.GetComponent<card>().destroyCard();

        int cardsLeft = GameObject.Find("Cards").transform.childCount;	// 1)
        Debug.Log(cardsLeft);
    }
    else
    {
        firstCard.GetComponent<card>().closeCard();
        secondCard.GetComponent<card>().closeCard();
    }

    firstCard = null;
    secondCard = null;
}

 

실행하면 맞춘 두장을 포함해서 나머지 갯수가 나옴

즉, 2가 나오면 마지막

 

c. 게임 끝내기

public GameObject endTxt;

public void isMatched()
{
    string firstCardImage = firstCard.transform.Find("front").GetComponent<SpriteRenderer>().sprite.name;
    string secondCardImage = secondCard.transform.Find("front").GetComponent<SpriteRenderer>().sprite.name;

    if (firstCardImage == secondCardImage)
    {
        firstCard.GetComponent<card>().destroyCard();
        secondCard.GetComponent<card>().destroyCard();

        int cardsLeft = GameObject.Find("Cards").transform.childCount;
        if (cardsLeft == 2)
        {
            endTxt.SetActive(true);
            Time.timeScale = 0.0f;
        }
    }
    else
    {
        firstCard.GetComponent<card>().closeCard();
        secondCard.GetComponent<card>().closeCard();
    }

    firstCard = null;
    secondCard = null;
}

 

d. 끝 버튼에 다시 시작하기 버튼 붙이기

1) 버튼 컴포넌트 추가하기

 

추가하고 연결하는 것 까지 하기!

 

2) endTxt.cs 만들고, endTxt에 붙이기

 

using UnityEngine.SceneManagement;

public void retryGame()
{
    SceneManager.LoadScene("MainScene");
}

 

### Warning!

[문제]

스크립트를 게임 오브젝트와 연결하려는데 오류가 났다 


[원인]

스크립트 파일 이름과 스크립트에서 구현되어 있는 클래스의 이름이 다르면 컴포넌트로 인식을 못해서 불러오지 못한다.

[해결]

클래스명을 수정했당! 오탈자 나서 수정만 했는데 이런 버그도 있구나 했다 ㅎㅋㅋ

 

3) gameManager.cs start에서 TimeScale을 다시 되돌려놓는 것도 잊지말기

 

Time.timeScale = 1.0f;

 

e. 확인하기

1) 마지막에 끝났을 때 카드가 없어지지 않고 끝나는 이슈

끝나는 부분을 Invoke로 0.5초 두고, GameEnd 함수로 따로 빼서 실행하면 됨!

 

public void IsMatched()
{
	...
	Invoke("GameEnd", 0.5f);
    ...
}

public void GameEnd()
{
    endTxt.SetActive(true);
    Time.timeScale = 0.0f;
}

 

잘 됐다!!

 

J. 숙제

1. 30초가 지나면 게임 끝내기

gameManager의 update부분에 아래 코드를 추가해준당!

 

if(time >= 30.0f)
{
    GameEnd();
}

 

 

 

K. 시작화면 만들기

1. 시작씬 만들기

a. StartScene 생성 및 설정하기

1) Scenes 폴더 → StartScene 만들기

 

 

2) StartScene으로 와서 카메라의 색 바꾸기

 

* 카메라 색 : 90, 90, 255

 

3) 이미지 넣기

 

* Image(UI) : 이러면 Canvas안에 생성됨

* name : rtans

reset 진행 후

* width : 400 / height: 400

* image는 rtan0 드래그

 

귀엽

 

4) 타이틀 만들기

 

a) Assets → Fonts 폴더 생성 → 폰트 파일 넣기

 

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

 

b) 타이틀 설정하기

 

위에서 만든 rtans 이미지가 들어있는 Canvas 자식으로 생성!

 

* y: 350

* width: 760, height: 200

* text: 르탄이를 찾아라

* 다운로드 받은 폰트 적용

* font-size: 70

* 가운데 정렬

* color: 255, 255, 255, 255

 

거리감이 있는 두 친구

 

5) 버튼 만들기

 

(a) 버튼 생성하기

 

동일한 Canvas 에서 Image(UI) 생성

 

* name : startBtn

* PosY: -400

* width: 360, height: 120

 

* add component → shadow 컴포넌트 추가

* distance: x: 10, y: -10

* color: 250, 250, 0 , 200

 

(b) 버튼 텍스트 생성하기

 

title 복사해서 startBtn 아래에 하나 생성

 

이렇게

 

* name: btnTxt

* PosY: 0

* width: 360, height: 120

* color: 0, 0, 0, 255

* text: 시작하기

 

깔끔하당!

 

 

2. 르탄이 이미지 애니메이션 넣기

a. 애니메이션 생성하기

(1) Animations 폴더 에서 rtans 애니메이션 생성

(2) rtans 이미지에 붙이기

 

b. 애니메이션 만들기

(1) 애니메이션 더블클릭하고, 르탄이 이미지 전체(0~7)를 끌어다놓기

(2) 오른쪽 바를 끌어서 40에 맞추기 

 

 

→ 르탄이가 빠르게 회전하는 것을 확인했으면 저장하고 끄기

 

 

3. startBtn 에 기능 만들기

a. startBtn.cs 만들기

using UnityEngine.SceneManagement;

public void startGame()
{
    SceneManager.LoadScene("MainScene");
}

 

b. 버튼 컴포넌트 만들고 클릭 붙이기

 

스크립트가 연결되어야만 startGame 함수를 연결할 수 있다 

 

c. 확인하기

최종-진짜최종.unity