본문 바로가기

Unity 공부/Unity_2D

[Day 12] 게임 시작과 종료 구현

[ 게임 시작과 종료 구현 ] --> 게임이 시작하고 끝날때의 UI 구현

  • Canvas 오브젝트에서 Create Empty(GameStart)
  • GameStart에서 UI --> Image생성(Title)
        - Sprites\UI폴더의 Title 0를 Source Image로 설정
        - Set Native Size 클릭
        - Scale을 1.5 | 1.5 | 1.5로 설정
        - Add Component --> Shadow
  • GameStart에서 UI -> Legacy --> Button생성(Button Start)
        - Width = 60 | Height = 20
        - Image = Panel
        - 컬러 선택 창의 스포이드로 Scene 화면의 UNDEAD색으로 설정(마음대로)
        - Navigation = None
        - Pos Y = -40
        - Add Component --> Shadow
  • Button Start\Text 설정
        - Font = neodgm
        - Text = 게임시작
        - Font Size = 10
        - Color = 하얀색
        - Add Component --> Outline
        - Effect Distance X = 0.6 | Y = -0.6
        - Color의 A값 최대로
        - 컬러 선택 창의 스포이드로 Scene 화면의 UNDEAD색으로 설정(마음대로)
  • Button Start의 On Click() +버튼 누르기
        - GameStart 오브젝트 넣기(드래그&드랍)
        - No Function을 GameObject --> SetActive(bool)로 설정
  • Canvas 오브젝트에서 Create Empty(HUD)
        - Exp, Level, Kill, Timer, Hp를 HUD에 넣어주기(드래그&드랍)
  • Button Start의 On Click() +버튼 누르기
        - HUD 오브젝트 넣기(드래그&드랍)
        - No Function을 GameObject --> SetActive(bool)로 설정
        - SetActive(bool) 체크
  • HUD 오브젝트 비활성화
  • 기존의 GameManager 스크립트에 코드 추가
    ㅡ아래는 완성된 코드ㅡ
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement; // SceneManager를 사용하기 위해 import

public class GameManager : MonoBehaviour
{
    public static GameManager instance;
    [Header("# Game Conrol")]
    public bool isLive;
    public float gameTime;
    public float maxGameTime = 2 * 10f;
    [Header("# Player Info")]
    public float hp;
    public float maxHp = 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; // Result 변수
    public GameObject enemyCleaner;

    private void Awake()
    {
        instance = this; 
    }

	// 기존의 Start()를 GameStart()로 변경
    public void GameStart()
    {
        hp = maxHp; 
        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 GameRetry()
    {
        SceneManager.LoadScene(0); // 장면 불러오기
    }

    void Update()
    {
        if(!isLive)
        {
            return;
        }
        gameTime += Time.deltaTime;

        if (gameTime > maxGameTime){ // 게임 시간을 모두 버팀
            gameTime = maxGameTime;
            GameVictory(); // 승리 함수 호출
        }
    }


    public void GetExp()
    {
        if (!isLive)
        {
            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;
    }

    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();
    }

}
  • Button Start의 On Click() +버튼 누르기
        - GameManager 오브젝트 넣기(드래그&드랍)
        - No Function을 GameManager --> GameStart()로 설정
  • 기존의 Player 스크립트에 코드 추가
    ㅡ아래는 완성된 코드ㅡ
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

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);
    }

    void Update()
    {
        if (!GameManager.instance.isLive)
            return;

        inputVec.x = Input.GetAxisRaw("Horizontal");
        inputVec.y = Input.GetAxisRaw("Vertical");
    }

    private void FixedUpdate()
    {
        if (!GameManager.instance.isLive)
            return;

        Vector2 nextVec = inputVec.normalized*speed* Time.fixedDeltaTime;
        rigid.MovePosition(rigid.position + nextVec);
    }

    private void LateUpdate()
    {
        if (!GameManager.instance.isLive)
            return;

        anim.SetFloat("Speed", inputVec.magnitude); 

        if (inputVec.x != 0) 
        {
            spriter.flipX = inputVec.x < 0;
        }
    }

    private void OnCollisionStay2D(Collision2D collision)
    {
        if (!GameManager.instance.isLive)
            return;

        GameManager.instance.hp -= Time.deltaTime * 10; // 프레임 단위로 데미지를 입음

        if (GameManager.instance.hp < 0)
        {
            for(int index=2; index<transform.childCount; index++) // 자식 오브젝트를 하나씩 접근
            {
                transform.GetChild(index).gameObject.SetActive(false); // 비활성화
            }

            anim.SetTrigger("Dead"); // 사망 애니메이션 트리거 설정
            GameManager.instance.GameOver();
        }
    }
}
  • GameStart를 Ctrl + D로 복사(GameResult)
        - Title의 Source Image를 Sprite\UI의 Title 2로 변경
        - Button Start --> Button Retry로 이름 변경
        - Button Retry의 On Click() 모두 삭제
        - Button Retry의 Text = 돌아가기
  • Button Retry의 On Click() +버튼 누르기
        - GameManager 오브젝트 넣어주기(드래그&드랍)
        - No Function을 GameManager --> GameRetry()로 설정
  • Canvas 오브젝트에 Create Empty(EnemyCleaner)
  • EnemyCleaner에 Add Component
        - Box Collider 2D
        - Bullet(Script)
        - Box Collider Size를 X = 1000 | Y = 1000
        - Damage = 10000000 | Per = -1
        - IsTrigger 체크
  • EnemyCleaner 비활성화
  • Title 이름 = Time Over, Time Over 복사
  • 복사된 Time Over 이름 = Time Victory
        - Source Image는 Sprite\UI의 Title 1으로 설정
        - Set Native Size 클릭
  • C# 스크립트 생성(Result)
    ㅡ아래는 완성된 코드ㅡ
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Result : MonoBehaviour
{
    public GameObject[] titles;

    public void Lose() // 지면
    {
        titles[0].SetActive(true); // Time Over 활성화
    }
    public void Win()
    {
        titles[1].SetActive(true); // Time Victory 활성화
    }
}
  • GameResult에 Add Component
        - Result(Script)
  • GameManager의 Ui Result에 GameResult 넣어주기(드래그&드랍)
  • GameManager의 enemyCleaner에 EnemyCleaner 넣어주기(드래그&드랍)
  • GameResult 오브젝트의 Titles = 2 변경
        - Element 0 = Time Over(오브젝트 드래그&드랍)
        - Element 1 = Time Victory(오브젝트 드래그&드랍)
  • Time Over/Victory 모두 비활성화
  • GameStart 활성화

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

 

★Slow and Steady★

'Unity 공부 > Unity_2D' 카테고리의 다른 글

[Day 14] 캐릭터 해금 시스템  (0) 2023.07.24
[Day 13] 플레이 캐릭터 선택  (0) 2023.07.19
[Day 11] 레벨업 시스템  (0) 2023.07.17
[Day 10] 무기 장착 표현  (0) 2023.07.16
[Day 9] 능력 업그레이드 구현  (0) 2023.07.15