[스파르타코딩클럽] 게임개발 종합반 - 1주차
[수업 목표]
- 유니티 다뤄보기
- C# 기본 문법 익히기
- 유니티 기본 사용법 익히기
[목차]
01. 1주차 오늘 배울 것
1) 게임개발종합반 수업의 목표와 범위
"어차피 게임 개발자들도 모든 유니티 코드를 외우고 있지 않습니다. 결국, 어떻게 동작하는지 대략적인 기능을 이해하고, 내가 필요한 부분을 찾아서 만들 수 있는 단계로 오르는 것이 중요합니다."
- 핵심: 유니티는 안 어렵습니다! 그런데, 처음에 사용법을 깔끔하게 설명해둔 곳이 없습니다!
- 4~5개를 만들어보게 되면, 결국 코드는 돌고 돈다-는 것을 알게 되실 거예요.
- C# 이라는 프로그래밍 언어를 사용하는데요, 이것은 하면서! 알려드리겠습니다. 😄
2) raindrop - 친환경 게임: 빗물 받는 르탄이
3) 5주 강의 구성
- 1주차 -
빗물 받는 르탄이
: 유니티 세팅, 기초 문법 연습 - 2주차 -
풍선을 구해라! 백만 다운로드 게임 따라만들기
: 유니티 기초 복습 - 3주차 -
고양이 밥주기 게임
: hp바, 레벨 연습하기 - 4주차 -
르탄이 카드 뒤집기 게임
: 보드 게임 기초 구현하기 - 5주차 -
주변 기능 학습
: 스플래시 화면 구성, 광고붙이기, 배포하기, 무료 에셋 구경하기
- 1주차 -
4) 오늘 만들 순서
(1) 유니티 - 기본 세팅, 씬 구성하기
(2) 캐릭터 왔다 갔다 하게 하기 + 클릭 시 방향 전환 구현
(3) 비 내리기 구현
(4) 비 충돌 구현
(5) UX (남은 시간 / 숫자합) 구현
(6) 게임 오버(팝업) 구현
02. 유니티 설치하기
1) OS별 각각의 다운로드 링크(Window / Mac)를 클릭해서 Unity-hub를 다운받습니다.
[코드스니펫] (Window) 유니티허브 다운로드
https://public-cdn.cloud.unity3d.com/hub/prod/UnityHubSetup.exe?_ga=2.197600431.1066071928.1631537679-831002153.1627910894
[코드스니펫] (Mac) 유니티허브 다운로드
https://public-cdn.cloud.unity3d.com/hub/prod/UnityHubSetup.dmg
2) 로그인 진행
로그인하기 클릭 후 회원가입 진행 → 구글로 로그인
3) 라이선스 발급받기
라이선스 관리 클릭
새 라이선스 활성화 클릭 → Personal → 완료
아래와 같은 화면이 나오면 발급 완료!
4) 유니티 설치하기
뒤로가기 눌러서 메인으로 돌아온 뒤 → 설치 → '추가' 클릭
아래 화면에서 '다음' 클릭
VisualStudio 클릭 + Android build supprt 클릭
맥의 경우 'Mac build support' / 윈도우의 경우 'Windows build support' 클릭
(모듈은 추후에도 추가할 수 있으니 잘못 체크했을까봐 너무 걱정 마세요!)
동의 → 동의 → 완료 클릭. 꽤 오랜 시간 (최장 20~30분까지) 기다리면 설치 완료!
마지막으로, 한국어 세팅하면 끝!
03. 기본 씬 구성 및 애니메이션 맛보기
1) 유니티에서 개발하기
게임 개발에 최적화된 개발 환경. 특히 2D 게임은 거의 100% 유니티로 개발한 것으로 생각하면 됨. 최근엔 대놓고 unity 로고를 보이는 게임들도 많음. 그림판 vs 포토샵.
프로젝트 생성 후 window → 아래와 같이 뷰 환경을 세팅!
project → 오른쪽 클릭 → one column layout 클릭
2) 각각 뭐 하는 뷰일까?
- Scene : 실제 게임의 구성요소를 보는 곳. 실질적인 게임 개발 씬
- Game : 게임이 실제로 보여지는 곳. play 버튼 클릭 후 볼 수 있음
- Hierachy : 게임 내 구성요소를 볼 수 있는 곳. 개발 시 자주 필요
- Project : 이 프로젝트에 포함된 파일들을 모아볼 수 있는 곳
- Inspector : 클릭한 요소의 속성과 정보를 보여주는 곳(차차 보면 알게 됨!)
3) 배경 세팅하기
메인 씬 이름 바꾸기
→ project에서 오른쪽 클릭 후 MainScene으로 변경
Game 씬 사이즈 바꾸기
→
+
버튼을 클릭하고 760 x 1280 Phone을 입력 → Phone 으로 변경배경 입히기
→ 2D Object → Sprite → Square 클릭 → background로 이름 바꾸기
→ 색을
255,255,220,255
로 맞추기→ Scale을
X:6, Y:10
으로 맞추기
4) UI박스(점수) 세팅하기
검은색 박스 만들기
→ 2D Object → Sprite → Square 클릭 → ground로 이름 바꾸기
→ 색을
50, 50, 50, 255
로 맞추기→ Scale을
X:6, Y:1.5
으로 맞추기 + Position은Y:-4.3
으로 맞추기→ order in layer를 1로 맞추기
'에셋'에 캐릭터 넣어두기
→ Assets 에서 Images 폴더 생성 → 르탄이 이미지 압축 풀고 끌어다놓기
3. 르탄이 캐릭터 만들기
→ 2D Object → Sprite → Square 클릭 → rtan으로 이름 바꾸기
→ Sprite 부분에 르탄이1 이미지 끌어다놓기
→ Order in Layer를 1로 바꾸기
→ position `Y:-2.9`
![Untitled](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/93acc45d-b094-43e3-ad72-bb05e3781ee6/Untitled.png)
5) 간단한 애니메이션을 입혀보기
애니메이션 폴더 만들기 (Asset → Animation)
애니메이션 파일을 만들고, Loop Time에 체크
이것을 만들어둔 르탄 캐릭터에 sprite에 끌어다놓기
Controller가 생긴 것을 확인!
→ Controller는 : Animation을 컨트롤 하는 것 (예 - 보통 상태 / 맞을 때 / 뛸 때 어떤 애니메이션을 써라)
→ Animation은 : 동작 파일
6) 기본 Animation 만들어보기
rtan_run.anim
더블 클릭 후 → 르탄이 캐릭터 클릭르탄이1, 2파일을 적당한 시간 간격으로 끌어다두기
Animator 간단 설명
→ 시작하면 무조건 rtan_run을 실행하게 되어있고
→ rtan_run은 끝이 없는 애니메이션임
실행해보면, 움직인다!
04. 캐릭터 움직이기
1) 먼저 세팅하기 : Visual Studio
윈) Edit → Preferences → External Tools → Visual Studio Community 2019로 맞추기
맥) Unity → Preferences → External Tools → Visual Studio for mac
2) 캐릭터에 코딩을 더하는 법
→ 유니티에서는, 캐릭터가 코드를 갖고 있을 수 있음
→ 즉, 캐릭터에 코드를 입히는 것. "너는 태어날 때 여기서 태어나고, 매 순간 이렇게 작동해라"
→ 가장 중요한 두 가지 함수가 있음. start (너는 태어날 때) / update (매 순간 이렇게 해라)
3) Script 만들기
→ Assets 우클릭 → Create → Folder (이름 Scripts) → Create → C# script (이름 rtan)
→ C#은? Microsoft가 개발한 코딩 개발 언어. 희한하게 유니티에서만 주류로 쓰이고 있다.
4) 캐릭터 좌우 움직임 코딩하기
1) 캐릭터 오른쪽으로 이동하기
→ 아래와 같이 입력하고 캐릭터에 스크립트를 끌여다 놓기
[코드스니펫] 캐릭터 오른쪽으로 이동하기
void Update() { transform.position += new Vector3(0.05f, 0, 0); }
```csharp
void Update()
{
transform.position += new Vector3(0.05f, 0, 0);
}
```
→ Play 버튼을 눌러보기 (캐릭터가 오른쪽으로 이동한다!)
![Untitled](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/40d4b96e-31cf-42d1-9270-5fe26045e685/Untitled.png)
→ transform의 의미: 캐릭터의 위치와 중, position을 계속 바꿔달라는 것
→ `transform.position += new Vector3(0.05f, 0, 0);`
→ 트랜스폼 안의 포지션을, Vector3 방향으로 계속 더해주세요
→ float 란? 소수점을 나타내는 자료형. 즉, 소수를 쓰고 싶으면 뒤에 f 를 붙여줘야 함
→ 위에 변수를 선언해서 이렇게 쓸 수도 있음!
```csharp
float direction = 0.05f;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
transform.position += new Vector3(direction, 0, 0);
}
```
- 2) 캐릭터가 벽에 닿으면 다른 방향을 보게 하기
→ 2-0) Debug.Log 로 위치 보기
- **[코드스니펫] Debug.log**
```csharp
Debug.Log(transform.position.x);
```
```csharp
Debug.Log(transform.position.x);
```
C#
→ 2-1) 760보다 클 때 다른 방향 보게 하기
- **[코드스니펫] 760보다 클 때 다른 방향 보게 하기**
```csharp
float direction = 0.05f;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (transform.position.x > 2.8f)
{
direction = -0.05f;
}
transform.position += new Vector3(direction, 0, 0);
}
```
```csharp
float direction = 0.05f;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (transform.position.x > 2.8f)
{
direction = -0.05f;
}
transform.position += new Vector3(direction, 0, 0);
}
```
→ 2-2) 0보다 작을 때 다른 방향 보게 하기
```csharp
float direction = 0.05f;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (transform.position.x > 2.8f)
{
direction = -0.05f;
}
if (transform.position.x < -2.8f)
{
direction = 0.05f;
}
transform.position += new Vector3(direction, 0, 0);
}
```
→ 📝(직접 해보기) 2-3) 방향 전환하기
(힌트1: "유니티 2d 좌우반전하기"로 검색)
(힌트2: 이런 코드를 만나면 굿! `transform.localScale = new Vector3(-1, 1, 1);` )
- **[코드스니펫] 방향 좌우반전하기**
```python
transform.localScale = new Vector3(-1, 1, 1);
```
- 펼치면 답!
```csharp
float direction = 0.05f;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (transform.position.x > 2.8f)
{
direction = -0.05f;
transform.localScale = new Vector3(-1, 1, 1);
}
if (transform.position.x < -2.8f)
{
direction = 0.05f;
transform.localScale = new Vector3(1, 1, 1);
}
transform.position += new Vector3(direction, 0, 0);
}
```
5) 클릭 시 움직임 바꾸기
위의 코드를 조금만 예쁘게 다듬고,
float direction = 0.05f; float toward = 1.0f; // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { if (transform.position.x > 2.8f) { direction = -0.05f; toward = -1.0f; } if (transform.position.x < -2.8f) { direction = 0.05f; toward = 1.0f; } transform.localScale = new Vector3(toward, 1, 1); transform.position += new Vector3(direction, 0, 0); }
마우스 클릭하면 → 움직이는 방향/이미지 방향 바꾸기
[코드스니펫] 마우스 클릭시 방향 바꾸기
if (Input.GetMouseButtonDown(0)) { toward *= -1; direction *= -1; }
```csharp
if (Input.GetMouseButtonDown(0))
{
toward *= -1;
direction *= -1;
}
```
05. 빗방울 코딩하기
[빗방울 내리게 하기]
1) 빗방울 특징
- 빗방울은 "하늘 랜덤한 위치에서 내림"
- 큰 / 중간 / 작은 빗방울 존재 (3-2-1점)
- 캐릭터와 부딪히면 점수 더하기
2) 빗방울 그리기
Sprite → Circle 클릭 → rain 으로 이름 바꾸기
→ 색을
150,150,255,255
으로 맞추기→ Position
Y:4
세팅하기
3) 빗방울 떨어지게 하기
rigidbody 2D를 달아 중력의 영향을 받게 하기
4) 땅에 닿으면 없어지게 하기(충돌 세팅)
circle collider 2d를 달고, 반경 조정. 자세히 보면 초록색 선이 보임!
바닥에도 box collider 2d를 달아주기
게임을 실행하면 땅과 충돌을 합니다.
5) 땅에 닿으면 없어지게 하기(충돌 조작)
"땅"인지 알 수 있게, ground 라고 tag를 주기
땅에 닿았는지 확인하기
→
rain
스크립트 만들고, 빗방울에 붙이기→
OnCollisionEnter2D
함수는 다른 콜라이더에 부딪혔을 때 실행되는 내장함수→ coll (부딪힌 것의) tag 가 ground 이면!
[코드스니펫] 땅에 닿았는지 확인하기
void OnCollisionEnter2D(Collision2D coll) { if (coll.gameObject.tag == "ground") { Debug.Log("땅이다!"); } }
```csharp
void OnCollisionEnter2D(Collision2D coll)
{
if (coll.gameObject.tag == "ground")
{
Debug.Log("땅이다!");
}
}
```
3. 비가 없어지게 하기
→ Debug.Log 대신, `Destroy(gameObject)`
→ gameObject는 나 자신
- **[코드스니펫] 비가 없어지게 하기**
```python
Destroy(gameObject);
```
```csharp
void OnCollisionEnter2D(Collision2D coll)
{
if (coll.gameObject.tag == "ground")
{
Destroy(gameObject);
}
}
```
[빗방울 랜덤하게 나타나게 하기]
1) 랜덤하게 위치 잡아주기
start() 함수에 랜덤 position 세팅하기
void Start() { float x = Random.Range(-2.7f, 2.7f); float y = Random.Range(3.0f, 5.0f); transform.position = new Vector3(x, y, 0); }
2) 랜덤하게 사이즈(큰/중간/작은) 잡아주기
어떤 사이즈로 나올지 생각하고 →
사이즈 변경:
transform.localScale = new Vector3(size, size, 0);
색 변경:
GetComponent<SpriteRenderer>().color = new Color(100 / 255f, 100 / 255f, 255 / 255f, 255 / 255f);
(참고 : 255.0f 로 나눠주는 게 핵심!)int type; float size; int score; // Start is called before the first frame update void Start() { float x = Random.Range(-2.7f, 2.7f); float y = Random.Range(3.0f, 5.0f); transform.position = new Vector3(x, y, 0); type = Random.Range(1, 4); if (type == 1) { size = 1.2f; score = 3; GetComponent<SpriteRenderer>().color = new Color(100 / 255f, 100 / 255f, 255 / 255f, 255 / 255f); } else if (type == 2) { size = 1.0f; score = 2; GetComponent<SpriteRenderer>().color = new Color(130 / 255f, 130 / 255f, 255 / 255f, 255 / 255f); } else { size = 0.8f; score = 1; GetComponent<SpriteRenderer>().color = new Color(150 / 255f, 150 / 255f, 255 / 255f, 255 / 255f); } transform.localScale = new Vector3(size, size, 0); }
[코드스니펫] type이 1일 때
size = 1.2f; score = 3; 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 = 0.8f; score = 1; GetComponent<SpriteRenderer>().color = new Color(150 / 255f, 150 / 255f, 255 / 255f, 255 / 255f);
[빗방울 계속 나오게 하기]
1) GameManager 만들기
예) 점수 / 다시 시작 / 3번 째 다시 시작에 부스터 / 광고보기 등
빈 곳에 object를 만들고 "gameManager"로 만들어둡니다.
마찬가지로 스크립트도 만들어 붙입니다. (어떻게 알았는지 아이콘 모양이 다르네요!)
2) 빗방울 복제하기 - Prefabs
프리팹 구현하기 (폴더 만들고 끌어다 놓기 & 오브젝트는 삭제)
3) 빗방울 복제하기 - Instantiate
gameManager에서 : 빗방울을 받기 + 프리팹 끌어다놓기
public GameObject rain;
0.5초마다 한번씩 실행되는 코드
[코드스니펫] InvokeRepeating 함수
InvokeRepeating("makeRain", 0, 0.5f);
[코드스니펫] makeRain 함수
void makeRain() { Debug.Log("비를 내려라!"); }
```csharp
void Start()
{
InvokeRepeating("makeRain", 0, 0.5f);
}
void makeRain()
{
Debug.Log("비를 내려라!");
}
```
3. 빗방울 프리팹을 복제하기
- **[코드스니펫] Instantiate 함수**
```csharp
Instantiate(rain);
```
```csharp
void makeRain()
{
Instantiate(rain);
}
```
06. 점수 올라가게 하기
1) 점수 보드 만들기
폰트 적용하기
→ Assets에 fonts 폴더 만들고 옮겨두기
[코드스니펫] 배민-한나체
http://pop.baemin.com/fonts/hanna11yrs/BMHANNA_11yrs_ttf.ttf
Sprite vs UI 그리고 Canvas
→
UI → Text
클릭 → 아래 설정을 따라하기 (폰트사이즈, 위치 등)text를 네 번 복사→붙여넣기 해서 아래와 같이 맞추기
2) gameManager - 싱글톤 화
[코드스니펫] 싱글톤 화
public static gameManager I; void Awake() { I = this; }
```csharp
public static gameManager I;
void Awake()
{
I = this;
}
```
3) gameManager - 점수 올라가는 함수 만들기
int totalScore = 0; public void addScore(int score) { totalScore += score; }
4) 빗방울 - 캐릭터에 맞으면 점수 올라가게 하기
캐릭터에 tag 주기 + collider 주기
빗방울 - 캐릭터에 맞으면 점수 올라가고 + 사라지기
void OnCollisionEnter2D(Collision2D coll) { if (coll.gameObject.tag == "ground") { Destroy(gameObject); } if (coll.gameObject.tag == "rtan") { gameManager.I.addScore(score); Destroy(gameObject); } }
gameManager - addScore 함수에 Debug.Log를 걸어서 확인 → 잘된다!
5) gameManager - 올라가는 점수 표기하기
UI Text 받기
using UnityEngine.UI;
public Text scoreText;
Text 바꿔주기
public void addScore(int score) { totalScore += score; scoreText.text = totalScore.ToString(); }
처음 스코어는 0으로 만들어주기
07. 게임 끝내기
1)
Retry
판넬 만들기정리하기 : 아래와 같이 세팅하기
→ image 사이즈: 400 / 250
→ txt 사이즈: 80
→ 글자 색상 (255, 255, 255, 255)
→ 배경 색상 (232, 52, 78, 255)
→ Inactive로 만들어두기
2) gameManager - 시간이 가게 하기
시간이 흐르게 하기
void Update() { limit -= Time.deltaTime; timeTxt.text = timeLimit.ToString("N2"); }
멈추게 하기
void Update() { limit -= Time.deltaTime; if (limit < 0) { Time.timeScale = 0.0f; limit = 0.0f; } timeTxt.text = timeLimit.ToString("N2"); }
3) 0초에 Retry 판넬 나오게하기
Panel 받기
public GameObject panel;
Panel 나오게 하기
void Update() { limit -= Time.deltaTime; if (limit < 0) { limit = 0.0f; panel.SetActive(true); Time.timeScale = 0.0f; } timeText.text = limit.ToString("N2"); }
4) 판넬 클릭하면 다시 시작하게 하기
판넬에 button 달기
씬 불러오는 것은 중앙에서 해야할 일! (gameManager.cs)
using UnityEngine.SceneManagement; public void retry() { SceneManager.LoadScene("MainScene"); }
클릭하면 작동 할 함수 만들기 (panel.cs)
[코드스니펫] panel.cs
public void retry() { gameManager.I.retry(); }
```csharp
public void retry()
{
gameManager.I.retry();
}
```
4. onclick 연결하기
![Untitled](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/8f3c7d45-7553-4b37-a00f-766acd4c1427/Untitled.png)
5) gameManager - 초기화 함수를 만들기
초기화 해야 할 요소들
→ timeScale, timeLimit, totalScore
void Start() { InvokeRepeating("makeRain", 0, 0.5f); initGame(); } void initGame() { Time.timeScale = 1.0f; totalScore = 0; limit = 30.0f; }
6) 수업 전체 코드
08. 숙제 - 빨강 빗방울 만들기
사이즈는
0.8
로 해주세요!색은
new Color(255 / 255.0f, 100.0f / 255.0f, 100.0f / 255.0f, 255.0f / 255.0f);
이렇게!이렇게 되면 완성!
힌트요정 - 👻
→
rain.cs
만 수정하면 된답니다!→
type = Random.range( ..
여기부터,if else
까지!
HW. 1주차 숙제 해설
new Color
new Color(255 / 255.0f, 100.0f / 255.0f, 100.0f / 255.0f, 255.0f / 255.0f);
rain.cs
코드