벌써 4번째 게임이다. 비슷한 부분은 모두 스킵하고 핵심만 콕콕 배워보자
빠르게 빠르게 기본적인 백그라운드 및 설정을 완료해준다
카드 디자인을 한 후 카드 프리팹을 만들어서 프리팹 폴더에 넣어주고
게임매니저 빈 Hierarchy와 스크립트를 제작해서 시간이 흐를 수 있게 코드를 작성하자
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GameManager : MonoBehaviour
{
public Text timeTxt;
float time = 0.0f;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
time += Time.deltaTime;
timeTxt.text = time.ToString("N2");
}
}
이제 코드를 통해 카드를 배치해보자.
보드 스크립트를 제작하고 수정하자.
4*4로 배치한다고 했을 때
이런 배치 좌표를 가지게 되는데 잘 보면 X값은 4*4배치에서 4로 나눈 나머지 값이고 Y값은 4로 나눈 몫이라고 볼 수 있다.
이걸 코드로 작성해보면
void Start()
{
for (int i = 0; i < 16; i++) //i가 16보다 작다면 반복, 반복 종료 시 i에 1을 더함
{
GameObject go = Instantiate(card, this.transform); //카드 오브젝트를 Board 밑으로 생성
float x = (i % 4) * 1.4f - 2.1f; //x좌표 4로 나눈 나머지값
float y = (i / 4) * 1.4f - 3.0f; //y좌표 4로 나눈 몫
go.transform.position = new Vector2(x, y); //x,y값에 생성
}
}
이렇게 나타낼 수 있다.
실행해보면?
깔끔하게 생성되었다.
지금은 각 카드에 하나의 이미지 밖에 없기 때문에 다양한 이미지를 가진 카드를 섞어서 실행할 때 마다 바뀌게 제작해보자.
우선 카드 스크립트를 작성하자.
public void Setting(int number)
{
idx = number;
}
0 ~ 7까지 같은 숫자를 2번 반복하는 배열을 만들면 같은 숫자가 2개씩 있는 16개의 배열이 만들어진다
넘버를 입력받으면 해당하는 그림으로 바뀔 수 있도록 카드에 속성을 추가해주었다.
보드 스크립트도 수정해주자.
public class Board : MonoBehaviour
{
public GameObject card;
// Start is called before the first frame update
void Start()
{
int[] arr = {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7}; //배열로 16개의 값을 추가
arr = arr.OrderBy(x => Random.Range(0f, 7f)).ToArray(); //배열을 랜덤한 값으로 재배열함
for (int i = 0; i < 16; i++) //i가 16보다 작다면 반복, 반복 종료 시 i에 1을 더함
{
GameObject go = Instantiate(card, this.transform); //카드 오브젝트를 Board 밑으로 생성
float x = (i % 4) * 1.4f - 2.1f; //x좌표 4로 나눈 나머지값
float y = (i / 4) * 1.4f - 3.0f; //y좌표 4로 나눈 몫
go.transform.position = new Vector2(x, y); //x,y값에 생성
go.GetComponent<Card>().Setting(arr[i]); //Card 컴포넌트 안의 Setting 함수에 arr[i]의 값을 입력
}
}
배열로 같은 숫자를 2개씩 8개의 조합으로 총 16개의 배열을 만들었다. 숫자가 같으면 같은 그림이 나오게 할 것이다.
이미지 폴더에서 리소스 폴더를 새로 만들어서 내용물을 전부 옮겨주고 리소스폴더 기능을 이용해서 작성해보자.
public class Card : MonoBehaviour
{
int idx = 0;
public SpriteRenderer front;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
public void Setting(int number)
{
idx = number;
front.sprite = Resources.Load<Sprite>($"rtan{idx}"); //$표시를 통해 문자열 내부에 변수 삽입 가능
}
}
카드가 흔들거리는 애니메이션과 눌렀을 때 뒤집어지는 애니메이션을 추가해주자.
두 가지 애니메이션을 만들고 각각 트랜지션으로 연결 해 준 후 컨디션에 isOpen이라는 bool값을 추가해주었다.
텍스트에 버튼 컴포넌트를 추가해 누르면 뒤집어 질 수 있도록 만들어보자.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Card : MonoBehaviour
{
int idx = 0;
public GameObject front;
public GameObject back;
public Animator anim;
public SpriteRenderer frontImage;
public void OpenCard()
{
anim.SetBool("isOpen", true);
front.SetActive(true);
back.SetActive(false);
}
}
앞면과 뒷면 오브젝트를 불러오고 애니메이터에 접근할 수 있게 anim 변수를 선언해 주었다.
OpenCard라는 함수를 만들어서 버튼에 연동시켜 누를 시 실행될 수 있도록 만들어주자.
이제 실행해보면?
이제 틀린 그림을 골랐을 경우 다시 뒤집어지게 만들어보자.
우선 카드 스크립트를 수정해보자.
public void DestroyCard() //카드가 맞다면 파괴하는 함수
{
Invoke("DestroyCardInvoke", 1.0f);
}
public void DestroyCardInvoke()
{
Destroy(gameObject);
}
public void CloseCard() //카드가 틀리다면 다시 뒤집는 함수
{
Invoke("CloseCardInvoke", 1.0f);
}
public void CloseCardInvoke()
{
anim.SetBool("isOpen", false);
front.SetActive(false);
back.SetActive(true);
}
Invoke를 하지 않으면 뒷 카드가 보이지도 않게 된다. 추가해주자
게임매니저 스크립트로 가서
public void Matched() //카드가 일치하는지 확인 하는 함수
{
if (firstCard.idx == secondCard.idx) //카드가 같다면
{
firstCard.DestroyCard();
secondCard.DestroyCard();
}
else //카드가 틀리다면
{
firstCard.CloseCard();
secondCard.CloseCard();
}
firstCard = null; //오브젝트 값 초기화
secondCard = null;
}
싱글톤 선언 후 함수를 추가로 만들어 주었다. 실행해보면?
그래도 잘 작동되는것 같아보인다.
마지막으로 엔드패널을 추가해 게임을 종료해보자.
게임 종료 시 출력 될 텍스트 UI를 추가한 후 잠시 꺼주자
게임매니저 스크립트에서 public int cardCount = 0;이라는 변수를 추가해준다.
보드 스크립트로 들어가서
void Start()
{
int[] arr = {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7}; //배열로 16개의 값을 추가
arr = arr.OrderBy(x => Random.Range(0f, 7f)).ToArray(); //배열을 랜덤한 값으로 재배열함
for (int i = 0; i < 16; i++) //i가 16보다 작다면 반복, 반복 종료 시 i에 1을 더함
{
GameObject go = Instantiate(card, this.transform); //카드 오브젝트를 Board 밑으로 생성
float x = (i % 4) * 1.4f - 2.1f; //x좌표 4로 나눈 나머지값
float y = (i / 4) * 1.4f - 3.0f; //y좌표 4로 나눈 몫
go.transform.position = new Vector2(x, y); //x,y값에 생성
go.GetComponent<Card>().Setting(arr[i]); //Card 컴포넌트 안의 Setting 함수에 arr[i]의 값을 입력
}
GameManager.Instance.cardCount = arr.Length; //카드카운트에 배열의 길이(16)을 추가
}
카드카운터에 arr.Length값을 입력해주고
다시 게임매니저로 돌아가 스크립트를 작성하자
public void Matched() //카드가 일치하는지 확인 하는 함수
{
if (firstCard.idx == secondCard.idx) //카드가 같다면
{
firstCard.DestroyCard();
secondCard.DestroyCard();
cardCount -= 2;
GameOver();
}
else //카드가 틀리다면
{
firstCard.CloseCard();
secondCard.CloseCard();
}
firstCard = null; //오브젝트 값 초기화
secondCard = null;
}
void GameOver()
{
if(cardCount == 0)
{
endTxt.gameObject.SetActive(true);
Time.timeScale = 0.0f;
}
}
카드가 같다면 카드 카운트를 줄이고 카드 카운트가 0이라면 게임오버 함수를 불러오게 설계했다.
실행해보면?
이제 끝 텍스트를 누르면 다시 실행하게 하고 마쳐보자.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class RetryBtn : MonoBehaviour
{
public void Retry()
{
SceneManager.LoadScene("MainScene");
}
}
까지 진행해서 오늘의 TIL은 마무리~
0830 TIL - 르탄이 카드 뒤집기 빌드와 광고 (1) | 2024.08.30 |
---|---|
0829 TIL - 테라리아 게임 분석 및 역기획 (0) | 2024.08.29 |
0827 TIL - 고양이 밥주기 게임 제작 (2) | 2024.08.27 |
0826 TIL - 풍선을 지켜라 게임 제작 (8) | 2024.08.26 |
0823 TIL - 빗물 받는 르탄 제작 _2 (0) | 2024.08.23 |