이어서
목차
5. 충돌 제어
6. 빗방울
7. 점수 및 UI 설정
8. 게임 끝내기
9. 과제 - 빨간 빗방울 생성
10. 최종 시현 영상
11. 마무리 및 느낀점
5. 충돌 제어
5-1 빗방울과 땅 충돌시
우선 땅(Ground) 인지 알 수 있게 Tag 값 생성
Untagged → Add Tag

+를 눌러 "Ground" Tag 생성

땅(Ground)에 Ground 태그 설정

5-2 충돌시 파괴
Rain 스크립트 생성
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.CompareTag("Ground")) // Tag 비교 → Ground와 충돌 했다면
{
Destroy(gameObject); //gameObject(Rain) 파괴
}
}
6. 빗방울
6-1 랜덤 값 설정
void Start()
{
float x = Random.Range(-2.4f, 2.4f);
float y = Random.Range(3.0f, 5.0f);
transform.position = new Vector3(x, y, 0);
}
6-2 타입 별 데이터 값
Type 1 속성 값
size = 0.8f;
score = 1;
GetComponent<SpriteRenderer>().color = new Color(100 / 255f, 100 / 255f, 255 / 255f, 255 / 255f);
Type 2 속성 값
size = 1.0f;
score = 2;
GetComponent<SpriteRenderer>().color = new Color(130 / 255f, 130 / 255f, 255 / 255f, 255 / 255f);
Type 3 속성 값
size = 1.2f;
score = 3;
GetComponent<SpriteRenderer>().color = new Color(150 / 255f, 150 / 255f, 255 / 255f, 255 / 255f);
6-3 완성 코드
float size;
int score;
SpriteRenderer renderer;
// Start is called before the first frame update
void Start()
{
renderer = GetComponent<SpriteRenderer>();
float x = Random.Range(-2.7f, 2.7f);
float y = Random.Range(3.0f, 5.0f);
transform.position = new Vector3(x, y, 0);
int type = Random.Range(1, 4);
if(type == 1)
{
size = 0.8f;
score = 1;
renderer.color = new Color(100 / 255f, 100 / 255f, 1f, 1f);
}
else if(type == 2)
{
size = 1.0f;
score = 2;
renderer.color = new Color(130 / 255f, 130 / 255f, 1f, 1f);
}
else if(type == 3)
{
size = 1.2f;
score = 3;
renderer.color = new Color(150 / 255f, 150 / 255f, 1f, 1f);
}
transform.localScale = new Vector3(size, size, 0);
}
6-4 GameManager 생성
게임 전체를 조율할 GameManager 생성
Hierarchy → Create Empty → 이름을 GameManager로 변경

6-5 Prefabs 생성
빗방울 제어를 위해 Assets → Create → Folder → Prefabs로 변경
만들어둔 Rain 오브젝트를 Prefabs에 넣기 → Hierarchy에 있는 Rain은 삭제

6-6 빗방울 복제
void Start()
{
InvokeRepeating("MakeRain", 0, 1f); // MakeRain 함수를 1초마다 반복해서 실행
}
void MakeRain()
{
Instantiate(rain); // rain 생성
}
7. 점수 및 UI 설정
7-1 UI
Hierarchy → UI → Legacy → Text → Text를 네 번 복사 → 아래 사진 참고하여 이름 설정 및 속성값 설정





7-2 싱글톤
// GameManager
public static GameManager Instance;
public void Awake()
{
Instance = this;
}
7-3 점수가 올라가는 함수
int totalScore = 0;
public void AddScore(int score)
{
totalScore += score;
}
7-4 캐릭터에 충돌 시 점수 증가
Rtan Sprite에 Player 태그 및 Collider 컴포넌트 추가


7-5 빗방울
플레이어와 충돌시에 점수를 올려주고 땅과 충돌시에 파괴
private void OnCollisionEnter2D(Collision2D collision)
{
if(collision.gameObject.CompareTag("Ground"))
{
Destroy(this.gameObject);
}
if (collision.gameObject.CompareTag("Player"))
{
GameManager.Instance.AddScore(score);
Destroy(this.gameObject);
}
}
7-6 올라가는 점수 생성
using UnityEngine.UI
public Text totalScoreTxt;
public void AddScore(int score)
{
totalScore += score;
totalScoreTxt.text = totalScore.ToString();
}
7-7 스코어 초기값
초기 값을 0으로 설정

8. 게임 끝내기
8-1 Retry
Retry Panel 생성 (Image 400 / 250 , Font Size 80, 색 R, G, B, A : 글자 색 255, 255, 255, 255, 배경 색 232, 52, 78, 255)
끝이 나면 UI가 보여야 하기에 Inactive 설정

8-2 시간이 흐르게 하기
플레이를 누르면 30초가 줄어들며 게임이 시작됨
// GameManager
public Text scoreText;
public Text timeText;
int totalScore = 0;
float totalTime = 30.0f;
void Update()
{
totalTime -= Time.deltaTime;
timeText.text = totalTime.ToString("N2");
}
8-3 시간을 멈추게 하기
토탈 타임이 0이 되면 시간을 멈춰 게임을 멈춘다
void Update()
{
if(totalTime > 0f)
{
totalTime -= Time.deltaTime;
}
else
{
Time.timeScale = 0.0f;
totalTime = 0.0f;
}
timeText.text = totalTime.ToString("N2");
}
8-4 Retry Panel 가시화
만들어둔 UI인 endpanel 를 GameManager로 제어 해야하므로 GameObject로 endPanel를 받는다.
public GameObject endPanel;
void Update()
{
if(totalTime > 0f)
{
totalTime -= Time.deltaTime;
}
else
{
totalTime = 0f;
endPanel.SetActive(true); // inactive 되어있는 패널을 totaltime이 0이 되면 가시화
Time.timeScale = 0f;
}
timeTxt.text = totalTime.ToString("N2");
}
8-5 다시 시작
endPanel에 Add Component → Button

8-6 retry 스크립트 생성
using UnityEngine;
using UnityEngine.SceneManagement;
public class RetryButton : MonoBehaviour
{
public void Retry()
{
SceneManager.LoadScene("MainScene");
}
}
+) endpanel에 RetryButton 스크립트를 붙이기
8-7 Button 설정
On.Click() → "+" → None에 endpanel(UI Text) 넣기 → No Function → retrybutton → retry()

8-8 게임 초기화
게임이 끝나고 멈춰있는 시간을 다시 흐를 수 있게 시간 값을 다시 설정해줌
//GameManager
private void Awake()
{
Instance = this;
Time.timeScale = 1.0f;
}
9. 과제 - 빨간 빗방울 생성
Score = -5 , Size = 0.8, 색상 빨간색
using System.Collections;
using UnityEngine;
public class red_rain : MonoBehaviour
{
float size = 0.8f;
int score = -5;
SpriteRenderer renderer;
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
int type = Random.Range(1, 2);
renderer = GetComponent<SpriteRenderer>();
float x = Random.Range(-2.4f, 2.4f);
float y = Random.Range(3f, 5f);
transform.position = new Vector3(x, y, 0);
if (type == 1)
{
size = 0.8f;
score = -5;
renderer.color = new Color(1f, 100f / 255f, 100f / 255f, 1f);
}
transform.localScale = new Vector3(size, size, 0);
}
// Update is called once per frame
void Update()
{
}
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.CompareTag("Ground"))
{
Destroy(this.gameObject);
}
if (collision.gameObject.CompareTag("Player"))
{
Destroy(this.gameObject);
Game_Manager.Instance.add_score(score);
}
}
}
10. 최종 시현 영상
11. 마무리 및 느낀점
전자공학과를 전공하고 많은 칩과 프로그램을 통해 전자 기기 제어를 한 경험이 새로운 프로그램 및 언어인
Unity와 C#에 진입장벽을 많이 낮춰주었다. 제어와 개발은 다른 매력을 가지고 있기에 보다 더 빠르게 흥미를 가지게 된 것 같다. 그리고 첫 프로젝트를 끝내게 되어 블로그 및 Unity, C# 모든 것이 입문의 단계이지만 몇 개월 뒤에는 내가 작성하고 개발하는 것들이 점차 쌓여 내 지식이 될 것이라 믿는다.
'게임 개발이 처음이어도 쉽게 배우는 모바일 게임 개발 > Sparta_Unity' 카테고리의 다른 글
고양이 밥주기 - 2 (0) | 2025.01.09 |
---|---|
고양이 밥주기 - 1 (0) | 2025.01.08 |
풍선을 지켜라 - 2 (0) | 2025.01.06 |
풍선을 지켜라 - 1 (1) | 2025.01.06 |
빗물받는 르탄이 - 1 (1) | 2025.01.04 |