일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 자료 구조
- 백준
- 수학
- 2025년
- c++
- 2022년
- 유니티 심화과정
- 2월
- 코딩 기초 트레이닝
- 5월
- 2023년
- 코딩 테스트
- 다이나믹 프로그래밍
- todolist
- 4월
- 10월
- 1월
- 단계별로 풀어보기
- 게임 엔진 공부
- 3월
- 기초
- 7월
- C/C++
- 입문
- 개인 프로젝트
- 개인 프로젝트 - 런앤건
- 유니티
- 프로그래머스
- 골드메탈
- 2024년
- Today
- Total
기록 보관소
[Unity/유니티] 기초-뱀서라이크: 게임 시작과 종료[13] 본문
개요
유니티 독학을 위해 아래 링크의 골드메탈님의 영상들을 보고 직접 따라 해보면서 진행 상황을 쓰고 배웠던 점을 요약한다.
https://youtube.com/playlist?list=PLO-mt5Iu5TeYI4dbYwWP8JqZMC9iuUIW2
📚유니티 기초 강좌
유니티 게임 개발을 배우고 싶은 분들을 위한 기초 강좌
www.youtube.com
뱀서라이크: 게임 시작과 종료[13]
1. 게임시작
- Shadow 컴포넌트 : UI 그래픽을 기준으로 그림자를 생성하는 컴포넌트.
- Outline 컴포넌트 : UI 그래픽을 기준으로 외각선을 그리는 컴포넌트.
//GameManager Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameManager : MonoBehaviour {
public static GameManager instance;
[Header("# Game Control")]
public bool isLive; //시간 정지 여부 확인 변수
public float gameTime; //게임 시간 변수
public float maxGameTime = 2 * 10f; //최대 게임 시간 변수(20초).
[Header("# Player Info")]
public int health;
public int maxHealth = 100;
public int level;
public int kill;
public int exp;
public int[] nextExp = { 3, 5, 10, 100, 150, 210, 280, 360, 450, 600 };
[Header("# Game Object")]
public PoolManager pool;
public Player player;
public LevelUp uiLevelUp;
void Awake() {
instance = this;
}
public void GameStart() {
health = maxHealth;
uiLevelUp.Select(0);//임시 스크립트 (첫번째 캐릭터 선택)
isLive = true;
}
void Update() {
if (!isLive)
return;
gameTime += Time.deltaTime;
if (gameTime > maxGameTime) {
gameTime = maxGameTime;
}
}
public void GetExp() {
exp++;
if (exp == nextExp[Mathf.Min(level, nextExp.Length - 1)]) {
level++;
exp = 0;
uiLevelUp.Show();
}
}
public void Stop() {
isLive = false;
Time.timeScale = 0;
}
public void Resume() {
isLive = true;
Time.timeScale = 1; //값이 1보다 크면 그만큼 시간이 빠르게 흐름. 모바일 게임에서 시간 가속하는 것이 이것..
}
}
2. 플레이어 피격
//GameManager Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameManager : MonoBehaviour {
public static GameManager instance;
[Header("# Game Control")]
public bool isLive; //시간 정지 여부 확인 변수
public float gameTime; //게임 시간 변수
public float maxGameTime = 2 * 10f; //최대 게임 시간 변수(20초).
[Header("# Player Info")]
public float health;
public float maxHealth = 100;
public int level;
public int kill;
public int exp;
public int[] nextExp = { 3, 5, 10, 100, 150, 210, 280, 360, 450, 600 };
[Header("# Game Object")]
public PoolManager pool;
public Player player;
public LevelUp uiLevelUp;
void Awake() {
instance = this;
}
public void GameStart() {
health = maxHealth;
uiLevelUp.Select(0);//임시 스크립트 (첫번째 캐릭터 선택)
isLive = true;
}
void Update() {
if (!isLive)
return;
gameTime += Time.deltaTime;
if (gameTime > maxGameTime) {
gameTime = maxGameTime;
}
}
public void GetExp() {
exp++;
if (exp == nextExp[Mathf.Min(level, nextExp.Length - 1)]) {
level++;
exp = 0;
uiLevelUp.Show();
}
}
public void Stop() {
isLive = false;
Time.timeScale = 0;
}
public void Resume() {
isLive = true;
Time.timeScale = 1; //값이 1보다 크면 그만큼 시간이 빠르게 흐름. 모바일 게임에서 시간 가속하는 것이 이것..
}
}
//Player Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class Player : MonoBehaviour {
public Vector2 inputVec; //키보드 입력 값 변수
public float speed; //속도 관리 변수
public Scanner scanner;
public Hand[] hands;
Rigidbody2D rigid;
SpriteRenderer spriter;
Animator anim;
void Awake() {
rigid = GetComponent<Rigidbody2D>();
spriter = GetComponent<SpriteRenderer>();
anim = GetComponent<Animator>();
scanner = GetComponent<Scanner>();
hands = GetComponentsInChildren<Hand>(true); //인자의 true를 통해서 비활성화된 오브젝트도 가능
}
void FixedUpdate() {
if (!GameManager.instance.isLive)
return;
//위치 이동
Vector2 nextVec = inputVec * speed * Time.fixedDeltaTime;
rigid.MovePosition(rigid.position + nextVec);
}
void OnMove(InputValue value) {
inputVec = value.Get<Vector2>();
}
void LateUpdate() {
if (!GameManager.instance.isLive)
return;
anim.SetFloat("Speed", inputVec.magnitude); //Magnitude : 벡터의 순수한 크기 값
if (inputVec.x != 0) {
spriter.flipX = inputVec.x < 0;
}
}
void OnCollisionStay2D(Collision2D collision) {
if (!GameManager.instance.isLive)
return;
GameManager.instance.health -= Time.deltaTime * 10;
if (GameManager.instance.health < 0) {
for (int index = 2; index < transform.childCount; index++) {
transform.GetChild(index).gameObject.SetActive(false);
}
anim.SetTrigger("Dead");
}
}
}
- 플레이어 피격시 체력이 잃는다. 체력이 0보다 낮아져서 죽으면 Dead 애니메이션이 출력된다.
- deltaTime을 사용해서 float형이 되었기에 GameManager의 health도 float으로 변경한다.
3. 게임 오버
//GameManager Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement; //장면 관리(Scene Manager 같은)를 사용하기 위한 네임스페이스.
public class GameManager : MonoBehaviour {
public static GameManager instance;
[Header("# Game Control")]
public bool isLive; //시간 정지 여부 확인 변수
public float gameTime; //게임 시간 변수
public float maxGameTime = 2 * 10f; //최대 게임 시간 변수(20초).
[Header("# Player Info")]
public float health;
public float maxHealth = 100;
public int level;
public int kill;
public int exp;
public int[] nextExp = { 3, 5, 10, 100, 150, 210, 280, 360, 450, 600 };
[Header("# Game Object")]
public PoolManager pool;
public Player player;
public LevelUp uiLevelUp;
public GameObject uiResult;
void Awake() {
instance = this;
}
public void GameStart() {
health = maxHealth;
uiLevelUp.Select(0);//임시 스크립트 (첫번째 캐릭터 선택)
isLive = true;
}
public void GameOver() {
StartCoroutine(GameOverRoutine());
}
IEnumerator GameOverRoutine() {
isLive = false;
yield return new WaitForSeconds(0.5f);
uiResult.SetActive(true);
Stop();
}
public void GameRetry() {
SceneManager.LoadScene(0); //LoadScene() : 이름 혹은 인덱스로 장면을 새롭게 부르는 함수
}
void Update() {
if (!isLive)
return;
gameTime += Time.deltaTime;
if (gameTime > maxGameTime) {
gameTime = maxGameTime;
}
}
public void GetExp() {
exp++;
if (exp == nextExp[Mathf.Min(level, nextExp.Length - 1)]) {
level++;
exp = 0;
uiLevelUp.Show();
}
}
public void Stop() {
isLive = false;
Time.timeScale = 0;
}
public void Resume() {
isLive = true;
Time.timeScale = 1; //값이 1보다 크면 그만큼 시간이 빠르게 흐름. 모바일 게임에서 시간 가속하는 것이 이것..
}
}
//Player Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class Player : MonoBehaviour {
public Vector2 inputVec; //키보드 입력 값 변수
public float speed; //속도 관리 변수
public Scanner scanner;
public Hand[] hands;
Rigidbody2D rigid;
SpriteRenderer spriter;
Animator anim;
void Awake() {
rigid = GetComponent<Rigidbody2D>();
spriter = GetComponent<SpriteRenderer>();
anim = GetComponent<Animator>();
scanner = GetComponent<Scanner>();
hands = GetComponentsInChildren<Hand>(true); //인자의 true를 통해서 비활성화된 오브젝트도 가능
}
void FixedUpdate() {
if (!GameManager.instance.isLive)
return;
//위치 이동
Vector2 nextVec = inputVec * speed * Time.fixedDeltaTime;
rigid.MovePosition(rigid.position + nextVec);
}
void OnMove(InputValue value) {
inputVec = value.Get<Vector2>();
}
void LateUpdate() {
if (!GameManager.instance.isLive)
return;
anim.SetFloat("Speed", inputVec.magnitude); //Magnitude : 벡터의 순수한 크기 값
if (inputVec.x != 0) {
spriter.flipX = inputVec.x < 0;
}
}
void OnCollisionStay2D(Collision2D collision) {
if (!GameManager.instance.isLive)
return;
GameManager.instance.health -= Time.deltaTime * 10;
if (GameManager.instance.health < 0) {
for (int index = 2; index < transform.childCount; index++) {
transform.GetChild(index).gameObject.SetActive(false);
}
anim.SetTrigger("Dead");
GameManager.instance.GameOver();
}
}
}
4. 게임 승리
- EnemyCleaner는 게임 승리시, 이름처럼 남은 몬스터들을 모두 제거하기 위한 오브젝트.
- 참고로 캡쳐한 시점에서 실수로 Tag를 지정하지 않았는데,Bullet을 지정해주어야 후에 테스트 실행시 EnemyCleaner가 정상 작동된다.
//Result Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Result : MonoBehaviour {
public GameObject[] titles;
public void Lose() {
titles[0].SetActive(true);
}
public void Win() {
titles[1].SetActive(true);
}
}
//GameManager Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement; //장면 관리(Scene Manager 같은)를 사용하기 위한 네임스페이스.
public class GameManager : MonoBehaviour {
public static GameManager instance;
[Header("# Game Control")]
public bool isLive; //시간 정지 여부 확인 변수
public float gameTime; //게임 시간 변수
public float maxGameTime = 2 * 10f; //최대 게임 시간 변수(20초).
[Header("# Player Info")]
public float health;
public float maxHealth = 100;
public int level;
public int kill;
public int exp;
public int[] nextExp = { 3, 5, 10, 100, 150, 210, 280, 360, 450, 600 };
[Header("# Game Object")]
public PoolManager pool;
public Player player;
public LevelUp uiLevelUp;
public Result uiResult;
void Awake() {
instance = this;
}
public void GameStart() {
health = maxHealth;
uiLevelUp.Select(0);//임시 스크립트 (첫번째 캐릭터 선택)
isLive = true;
}
public void GameOver() {
StartCoroutine(GameOverRoutine());
}
IEnumerator GameOverRoutine() {
isLive = false;
yield return new WaitForSeconds(0.5f);
uiResult.gameObject.SetActive(true);
uiResult.Lose();
Stop();
}
public void GameRetry() {
SceneManager.LoadScene(0); //LoadScene() : 이름 혹은 인덱스로 장면을 새롭게 부르는 함수
}
void Update() {
if (!isLive)
return;
gameTime += Time.deltaTime;
if (gameTime > maxGameTime) {
gameTime = maxGameTime;
}
}
public void GetExp() {
exp++;
if (exp == nextExp[Mathf.Min(level, nextExp.Length - 1)]) {
level++;
exp = 0;
uiLevelUp.Show();
}
}
public void Stop() {
isLive = false;
Time.timeScale = 0;
}
public void Resume() {
isLive = true;
Time.timeScale = 1; //값이 1보다 크면 그만큼 시간이 빠르게 흐름. 모바일 게임에서 시간 가속하는 것이 이것..
}
}
- 게임 승리시 처리를 위해 GameManger를 추가 수정
//GameManager Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement; //장면 관리(Scene Manager 같은)를 사용하기 위한 네임스페이스.
public class GameManager : MonoBehaviour {
public static GameManager instance;
[Header("# Game Control")]
public bool isLive; //시간 정지 여부 확인 변수
public float gameTime; //게임 시간 변수
public float maxGameTime = 2 * 10f; //최대 게임 시간 변수(20초).
[Header("# Player Info")]
public float health;
public float maxHealth = 100;
public int level;
public int kill;
public int exp;
public int[] nextExp = { 3, 5, 10, 100, 150, 210, 280, 360, 450, 600 };
[Header("# Game Object")]
public PoolManager pool;
public Player player;
public LevelUp uiLevelUp;
public Result uiResult;
public GameObject enemyCleaner;
void Awake() {
instance = this;
}
public void GameStart() {
health = maxHealth;
uiLevelUp.Select(0);//임시 스크립트 (첫번째 캐릭터 선택)
Resume();
}
public void GameOver() {
StartCoroutine(GameOverRoutine());
}
IEnumerator GameOverRoutine() {
isLive = false;
yield return new WaitForSeconds(0.5f);
uiResult.gameObject.SetActive(true);
uiResult.Lose();
Stop();
}
public void GameVictory() {
StartCoroutine(GameVictoryRoutine());
}
IEnumerator GameVictoryRoutine() {
isLive = false;
enemyCleaner.SetActive(true);
yield return new WaitForSeconds(0.5f);
uiResult.gameObject.SetActive(true);
uiResult.Win();
Stop();
}
public void GameRetry() {
SceneManager.LoadScene(0); //LoadScene() : 이름 혹은 인덱스로 장면을 새롭게 부르는 함수
}
void Update() {
if (!isLive)
return;
gameTime += Time.deltaTime;
if (gameTime > maxGameTime) {
gameTime = maxGameTime;
GameVictory();
}
}
public void GetExp() {
if (!isLive) //EnemyCleaner로 경험치를 못얻게 하기 위함
return;
exp++;
if (exp == nextExp[Mathf.Min(level, nextExp.Length - 1)]) {
level++;
exp = 0;
uiLevelUp.Show();
}
}
public void Stop() {
isLive = false;
Time.timeScale = 0;
}
public void Resume() {
isLive = true;
Time.timeScale = 1; //값이 1보다 크면 그만큼 시간이 빠르게 흐름. 모바일 게임에서 시간 가속하는 것이 이것..
}
}
'유니티 프로젝트 > 뱀서라이크' 카테고리의 다른 글
[Unity/유니티] 기초-뱀서라이크: 캐릭터 해금 시스템[14+] (0) | 2023.07.25 |
---|---|
[Unity/유니티] 기초-뱀서라이크: 플레이 캐릭터 선택[14] (0) | 2023.07.21 |
[Unity/유니티] 기초-뱀서라이크: 레벨업 시스템[12] (0) | 2023.07.14 |
[Unity/유니티] 기초-뱀서라이크: 플레이어 무기 장착 표현하기[11+] (0) | 2023.07.13 |
[Unity/유니티] 기초-뱀서라이크: 능력 업그레이드 구현[11] (0) | 2023.07.12 |