Unity 미니 팀 프로젝트

Amberjack·2023년 12월 26일
0

Unity

목록 보기
4/44
post-custom-banner

미니 팀 프로젝트

Unity - 4주차에 만든 카드 뒤집기 게임을 활용하여 팀원을 소개하는 카드 게임 만들기

내가 해야할 과제

  1. 결과 화면 만들기
  2. 결과 화면에 카드 매칭 시도 횟수 표시하기
  3. 첫 번째 카드 고르고 5초 동안 두 번째 카드를 고르지 않는다면 다시 뒤집기
  4. 결과 화면에 점수 표시하기
  5. 결과 화면에 다시하기 버튼 및 시작 화면으로 나가는 버튼 만들기

결과 화면(endPanel) 만들기

만들어진 화면 ▼

카드 매칭 시도 횟수 표시하기

endPanel 내에 시도 횟수 표시를 위한 tryCount를 만든다.

시도 횟수(label)

시도 횟수 표시(count)

GameManager.cs에 count를 붙이고, 코드를 작성해준다.

  1. isMatched()가 호출될 때마다 counter를 더해준다.

    public void isMatched()
    {
    	counter++;
        ...
    }
  2. 이 후 GameEnd()가 실행될 때 counter를 text로 보내준다.

    void GameEnd()
    {
    	endPanel.SetActive(true);
       
        count.text = counter.ToString();
    }

첫 번째 카드 고른 후 5초 동안 두 번째 카드를 안 고르면 다시 뒤집기

고민해보기

  1. 첫 번째 카드를 뒤집을 때의 게임 내 시간을 저장한다.
  2. 현재 시간과 저장된 시간의 차가 5초 이상 날 경우 카드를 다시 뒤집는다!

첫 번째 카드를 뒤집을 때의 게임 내 시간을 저장.

  1. openCard() 함수가 호출되어 첫 번째 카드가 뒤집어질 때의 시간을 저장한다.

    public void openCard()
    {
    	...
    
        if(GameManager.I.firstCard == null)
        {
        	GameManager.I.firstCard = gameObject;
           
            // 첫 번째 카드가 뒤집힌 시간 저장하기
            check_time = GameManager.I.time;
        }
        ...
    }
  2. 이 후 Update()에서 현재 시간과 check_time을 비교하여 5초가 차이날 경우 첫 번째 카드를 다시 뒤집는다.

    void Update()
    {
    	if(check_time - GameManager.I.time >= 5.0f)
        {
        	check_time = 0.0f;
            GameManager.I.firstCard.GetComponent<card>().closeCard();
    
      		GameManager.I.firstCard = null;
    }

문제점 발생!

코드를 작성하고 테스트를 해보던 중, 카드를 한 번에 2장 이상 뒤집을 수 있음을 확인했다.
해당 문제는 게임의 특성과 맞지 않기도 하고, 2장의 카드가 아직 뒤집히거나 사라지지 않았을 때 세 번째 카드를 뒤집으면 5초보다 더 빨리 다시 뒤집어지는 문제가 발생했기 때문에 수정했다.

수정 방법은 GameManager.cs에 현재 게임에 뒤집힌 카드 개수를 관리하는 cardCounter를 만들고, cardCounter가 2 이상이 되면 openCard()에서 return;을 하는 방식으로 해결했다.

자세한 수정 내용 : https://velog.io/@amberjack/TIL-23.12.22

결과 화면에 점수 표시하기

점수 산출 방식?

  1. 카드 한 쌍을 맞출 때 점수를 +, 틀릴 때마다 -
  2. 제한 시간에서 남은 시간만큼 점수로 환산하기
  3. 난이도 별로 차감되는 점수를 늘리기?

카드 맞출 때 +, 틀릴 때 -

  1. isMatched()에서 카드가 같을 경우 score += 10;을 해주었다.
  2. 틀릴 경우 또한 마찬가지로 isMatched()에 작성했으나, 0점보다 더 작아지지 않도록 했다.
    score -= 5;
    if(score <= 0) score = 0;

제한 시간에서 남은 시간만큼 점수로 환산하기

이 경우, 게임이 끝나고 GameEnd()함수가 불릴 때 계산하도록 작성했다.

남은 시간 / 10 * 5만큼 점수에 +되도록 작성했다.

void GameEnd()
{
	// 결과창 띄우기
	endPanel.SetActive(true);

	// 남은 시간의 십의 자리 수 * 5 만큼 점수 더해주기
	// score += (int)(제한시간 - time) / 10 * 5;
	score += (int)(30.0f - time) / 10 * 5;
	// 점수 표기
	scoreTxt.text = score.ToString();

	count.text = counter.ToString();
	Time.timeScale = 0f;
	audioManager.SetActive(false);
}

실행 화면

결과 화면에 버튼 추가하기

시작 화면으로 나가는 버튼 만들기

// exitBtn.cs
public void exit()
{
	SceneManager.LoadScene("StartScene");
}

문제점 발생!!!

😱 팀원들과 코드를 합쳐본 결과, 문제가 발생했다!
👉 다른 팀원 중 '카드 두 장을 뒤집었을 때 다를 경우 시간 감소'를 작업하는 분이 계셨는데, 이 때 나와 같은 GameManager.I.time 변수를 사용하셔서 서로 충돌이 발생한 것이다.
ex) 틀렸을 때의 시간 감소 : 5초 인 경우, 카드 2장을 뒤집어서 틀렸을 때 5초 감소가 내 if문의 조건에 맞았기 때문에 if문으로 진입하지만, 이미 firstCard를 destroy 했기 때문에 Null을 참조하며 문제가 발생했던 것이다.

해결 방법... :

😥 여러 방법을 생각해보았지만, 결국 진짜 게임 시간을 관리하는 gameTime을 만들어 해결할 수 밖에 없었다...

느낀 점 :

😂어쨌든 이 문제를 해결하러 게임 시간을 직접 비교하려는 시도를 했었다.
if(Time.deltaTime - check_time >= 5.0f)을 사용하려 했으나, if문에 진입하지 못했다. Time.deltaTime에 연산을 할 수 없는 것일까?

그러나 이 문제를 해결하려 구글링을 한 덕에 여러 시간 관련 코드들을 볼 수 있었다.

DateTime을 통해 시간 비교하기

DateTime의 초 단위를 사용해서 비교를 해보려고 구글링을 해봤다.
출처 : https://gdlseed.tistory.com/68

DateTime start = DateTime.Now;
DateTime end;

Invoke("getEnd", 5.0f);

TimeSpan dateDiff = end - start;

int diffSecond = dateDiff.Seconds;		// diffSecond : 5
post-custom-banner

0개의 댓글