✅ 오늘의 학습
1. Cat 횡 스크롤 게임 [다시 하기] 기능 만들기
2. CCTV와 MiniMap 만들어보기
3. Random을 활용한 Lotto 구현
1. Cat 게임 [다시하기] 기능 만들기
1. OnEnable() 활용
1.1. 고양이 위치
게임 종료를 구현한 코드를 살펴보면,
CatController의 EndingRoutine() 코루틴에서 UI들을 비활성화하고 소리를 끄도록 구현해 두었다.
// CatController 스크립트
IEnumerator EndigRoutine(bool isHappy)
{
yield return new WaitForSeconds(3.5f);
videoManager.VideoPlay(isHappy);
// bool 값이 true가 될 때까지 대기
// yield return new WaitUntil(() => videoManager.vPlayer.isPlaying);
fadeUI.SetActive(false);
gameOverUI.SetActive(false);
soundManager.audioSource.mute = true;
}
이 상태에서 게임을 다시 시작하면, 고양이의 위치가 그대로 유지되는 문제가 발생하기 때문에 OnEnable()을 활용해 게임이 다시 시작될 때 고양이 위치와 UI 상태를 초기화하도록 했다.
void Awake()
{
catRb = GetComponent<Rigidbody2D>();
catAnim = GetComponent<Animator>();
}
// 켜질 때마다 1번씩 실행
void OnEnable()
{
transform.localPosition = new Vector3(-5.58599854f, -2.04101563f, 0.159999996f);
GetComponent<CircleCollider2D>().enabled = true;
soundManager.audioSource.mute = false;
}
1.2. 아이템 위치
아이템은 처음 생성될 때 SetRandomSetting()을 통해 랜덤 위치에 배치되도록 되어 있다.
// ItemEvent 스크립트
void Start()
{
SetRandomSetting(transform.position.x);
}
하지만 게임이 종료되었을 때 아이템이 존재한 위치를 그대로 기억하고 있어, 게임을 다시 시작했을 때도 같은 위치에 그대로 있기 때문에 Awake()에서 초기 위치를 저장하고 OnEnable()에서 다시 랜덤 배치되도록 수정했다.
private Vector3 initPos;
void Awake()
{
initPos = transform.localPosition;
}
void OnEnalbe()
{
SetRandomSetting(initPos.x);
}
2. Button 만들기
게임이 종료되었을 때 다시하기 버튼이 나타나도록 Ending Panel 하위에 버튼을 생성해 주었다.

기존에 Button의 동작은 UIManager에서 관리해 주었으니 해당 스크립트에 다시하기 버튼의 동작도 구현해 보자
// UIManager 스크립트에 추가
public Button reStartButton;
void Start()
{
reStartButton.onClick.AddListener(OnRestartButton);
}
public void OnRestartButton()
{
playObj.SetActive(true);
}
그리고 재시작되었을 때 [게임 시간]과 [Score]의 값도 초기화되어야 하니 이 부분을 구현한 GameManager 스크립트에 해당 내용을 추가해 준다.
// GameManager 스크립트
private static float timer;
public static int score;
public static void ResetPlayUI()
{
timer = 0f;
score = 0;
}
static으로 선언하면 객체 없이 클래스 이름으로 바로 사용할 수 있다. (static이 아니면, 객체를 먼저 만들어서 그걸 통해 접근해야 한다.)
// UIManager 스크립트
public void OnRestartButton()
{
GameManager.ResetPlayUI();
playObj.SetActive(true);
videoPanel.SetActive(false);
}
다시 UIManager 스크립트로 돌아와서 [다시하기] 버튼을 눌렀을 때 [시간]과 [점수]를 초기화하는 GamaManager 메서드를 호출하고, [엔딩 패널]이 비활성화되도록 설정해 준다.

잊지 말고 유니티 에디터에 오브젝트들 다 적용해 주기!

이렇게 모든 작업을 완료하면 고양이와 아이템들의 위치, 플레이 시간과 점수가 모두 초기화되는 것을 확인할 수 있다.
3. Fade 조절
게임이 성공/실패할 때 비디오가 갑자기 뽷! 나타나면서 시각적으로 너무 갑작스러운 느낌을 준다.
이 부분을 조금 더 자연스럽게 전환하기 위해 Fade 연출을 추가해 주겠다.
// FadePanel 스크립트
IEnumerator FadeRoutine(float fadeTime, Color color, bool isFadeStart)
{
float timer = 0f;
float percent = 0f;
while (percent < 1f)
{
// 게임이 시작될 때와 종료될 때 다른 fade 값을 넣어주기 위해 변수 생성
float value = isFadeStart ? percent : 1 - percent;
timer += Time.deltaTime;
percent = timer / fadeTime; // Fade 퍼센트
fadePanel.color = new Color(color.r, color.g, color.b, value);
yield return null;
}
}
먼저 FadePanel 스크립트에 있는 FadeRoutine 코루틴을 수정해 준다.
패널이 Fade-In → 영상 재생 → Fade-Out 흐름으로 작동해야 하므로 isFadeStart라는 bool 변수를 추가해서 구분해 주었다.
// CatController 스크립트
// 게임 성공
fadeUI.GetComponent<FadePanel>().OnFade(3f, Color.white, true);
// 게임 실패
fadeUI.GetComponent<FadePanel>().OnFade(3f, Color.black, true);
IEnumerator EndigRoutine(bool isHappy)
{
yield return new WaitForSeconds(3.5f);
videoManager.VideoPlay(isHappy);
yield return new WaitForSeconds(1f);
var newColor = isHappy ? Color.white : Color.black;
fadeUI.GetComponent<FadePanel>().OnFade(3f, newColor, false);
Debug.Log("페이드 해제중");
yield return new WaitForSeconds(3f);
fadeUI.SetActive(false);
gameOverUI.SetActive(false);
soundManager.audioSource.mute = true;
// 가장 나중에 꺼야 원활히 작동 됨
transform.parent.gameObject.SetActive(false); // PLAY 오브젝트 OFF
}
bool의 값에 따라 fade In/Out 되도록 코드를 삼항연산자로 수정해 주면 끝!

2. CCTV 카메라 & 미니맵
이전에 실습한 Door Animation 씬에서 문에 걸려있는 CCTV를 구현해 보겠다.
🥕 예행 작업
1. 씬에 TV 배치
2. 문 위에 새로운 Camera 배치
1. CCTV

하나의 씬에 카메라가 여러 개 있을 경우 어떤 카메라가 메인인지 식별하기 어렵기 때문에 Gizmo(기즈모)를 활용해 시각적으로 구분해 주는 것이 좋다.

Render Texture를 새로 생성하여 CCTV용 카메라에 적용한다.

Raw Image UI 오브젝트를 생성한 뒤 그 안에 Render Texture를 연결해 준다.
이때, Canvas의 Render Mode를 "World Space"로 설정해 주면 TV 화면처럼 원하는 위치에 자유롭게 띄울 수 있다.


이렇게 하면 TV 화면에 CCTV 카메라가 나타나는데,
CCTV 화면의 해상도가 너무 낮게 보인다면 Render Texture의 Size를 직접 조절해 주면 된다.
2. 미니맵
미니맵도 CCTV 구현한 것과 똑같이 카메라&렌더 텍스쳐 만들고 캔버스 설정만 다르게 해주면 된다.

카메라를 플레이어 위에 배치해 줄 것이기 때문에 2D 화면에 적합한 Orthographic로 적용해 주어도 무방하다.

대신 이번에는 카메라를 월드 내 어딘가에 배치하는 것이 아니라 게임 씬 화면에 나타나야 하므로 캔버스 렌더 모드를 Overlay로 해주어야 한다.

그런 다음 씬에 배치된 오브젝트 머리 위에 오브젝트 위치를 표시할만한 것을 배치해 준다.

캐릭터가 움직일 때마다 미니맵에 잘 반영되는 것을 확인할 수 있다!
3. Lotto
🥕 예행 작업
1. Scene 생성 (Lotto)
2. Scripts 생성 (LottoGenerator)
3. Object 생성 (LottoGenerator) - 빈 오브젝트로 생성해 주고 스크립트를 적용해 준다.
Lotto 시스템을 구현하기 위해서 Random를 활용해서 Swap과 Shuffle 작업을 해주려고 한다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LottoGenerator : MonoBehaviour
{
public List<int> intList = new List<int>();
public int shakeCount = 100;
private void Awake()
{
for (int i = 1; i < 46; i++)
{
intList.Add(i);
}
}
IEnumerator Start()
{
for (int i = 0; i < shakeCount; i++)
{
int ranInt1 = Random.Range(0, intList.Count);
int ranInt2 = Random.Range(0, intList.Count);
var temp = intList[ranInt1];
intList[ranInt1] = intList[ranInt2];
intList[ranInt2] = temp;
yield return new WaitForSeconds(0.025f);
}
List<int> resultGroup = new List<int>();
for (int i = 0; i < 6; i++)
resultGroup.Add(intList[i]);
resultGroup.Sort();
string resultNumber = $"이번 주 로또 번호 : {resultGroup[0]} / {resultGroup[1]} / {resultGroup[2]}" +
$"/ {resultGroup[3]} / {resultGroup[4]} / {resultGroup[5]} " +
$"/ 보너스 넘버 : {intList[6]}";
Debug.Log(resultNumber);
}
}

오늘 포스팅은 어제 실습한 내용과 크게 다른 점이 없다고 생각해서 많은 부분이 생략되었다.
요즘 그냥 포스팅에 많은 정성을 들이지 않고있다..!
어느정도 유니티 에디터 사용법에 익히게 되어서 오브젝트 만드는거나 인스펙터 부분을 특히 많이 생략했다..
혹시 누군가 이 글을 보면서 복습하는데 도움이 되신다면.. 타인도 알아보기 쉽게 작성하려고 노력해보겠습니다.. ㅎㅎ
'Unity > 멋쟁이사자처럼 부트캠프' 카테고리의 다른 글
| [멋쟁이사자처럼부트캠프] 유니티 게임 개발 5기(22일차) - Interface(인터페이스)를 활용한 스크립트 작성 (0) | 2025.06.16 |
|---|---|
| [멋쟁이사자처럼부트캠프] 유니티 게임 개발 5기(21일차) - C# 기초(10) / 형 변환과 상속의 개념 (1) | 2025.06.13 |
| [멋쟁이사자처럼부트캠프] 유니티 게임 개발 5기(19일차) - Video 심층 학습 및 TV 리모컨 구현부터 게임 빌드까지! (0) | 2025.06.11 |
| [멋쟁이사자처럼부트캠프] 유니티 게임 개발 5기(18일차) - Cat 횡 스크롤 게임 업그레이드 (0) | 2025.06.10 |
| [멋쟁이사자처럼부트캠프] 유니티 게임 개발 5기(17일차) - C# 기초(9) (0) | 2025.06.09 |