[unity]- 2d 도트 기초 [ 스테이지 게임 완성 ]
>점수 얻을수 있는 코인 추가하기
코인은 다른 물체들과 충돌이 일어나면 안된다.
플레이어는 코인을 먹어야 점수를 얻을수있고 몹도 코인과 충돌하면 안되기 때문.

코인의 collider에서 is Trigger부분을 체크해주면 충돌이 일어나지 않는다.
>스테이지 추가
tile palatte를 통해서 스테이지를 만들어준다.
스테이지를 만들때 다른 스테이지는 안보이게 한 후 만들어주는것이 좋다.



다 만들고나서는 스테이지 1만 활성화 시켜준다.
>GameManager

새로 create empty를 만들어 이름을 GameManager로 바꿔준다.
같은 이름으로 스크립트도 만든다. 이는 점수와 스테이지들을 관리해준다.
코드를 살펴보면,
using JetBrains.Annotations;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using UnityEngine.SceneManagement;
-UI를 사용해야해서 추가해주고, TMPro는 텍스트를 위해서 추가해준다.
SceneManagement는 원하는 Scene을 볼수있다.
public int totalPoint;
public int stagePoint;
public int stageIndex;
public int health;
public PlayerMove player;
public GameObject[] Stages;
public Image[] UIhealth;
public TextMeshProUGUI UIPoint;
public TextMeshProUGUI UIStage;
public GameObject UIRestartBtn;
Rigidbody2D rigid;
SpriteRenderer spriteRenderer;
Animator anim;
CapsuleCollider2D capsulecollider;
AudioSource audioSource;
totalPoint는 누적 점수, stagePoint는 스테이지 자체에서 얻은 점수,
stageIndex는 스테이지 번호, health는 피 상태이다.
PlayerMove라는 클래스의 객체를 player라고 선언한다.
GameObject들을 배열을 사용하여 Stages로 선언한다.
Image들을 배열을 사용하여 UIhealth로 선언한다.
Text를 선언하려면 저렇게 사용해야한다.
GameObject로 다시시작하는 버튼을 선언한다.

GameObject면 모든 오브젝트들을 사용할수있다. Stage자리에 이미지나 텍스트가 들어갈수도있다.
하지만 Image면 이미지만 사용할수있고 text도 마찬가지이다.
>Update문
void Update()
{
UIPoint.text = (totalPoint + stagePoint).ToString();
}
UI중에 점수부분의 텍스트가 계속 갱신되어야하므로 Update에 해준다.
totalPoint랑 stagePoint는 정수이므로 문자열로 변환시켜서 text에 대입한다.
>다음스테이지 넘어가는 함수
public void NextStage()
{
//change Stage
if(stageIndex< Stages.Length-1)
{
Stages[stageIndex].SetActive(false);
stageIndex++;
Stages[stageIndex].SetActive(true);
PlayerReposition();
UIStage.text = "STAGE " + (stageIndex+1);
}
else//gameclear
{
Time.timeScale = 0; //시간멈춰둔다
//restart button ui
TextMeshProUGUI btnText=UIRestartBtn.GetComponentInChildren<TextMeshProUGUI>(); //text는 자식오브젝트라서.
btnText.text = "Clear!";
ViewBtn();
}
//calculate point
totalPoint += stagePoint;
stagePoint = 0;
}
stage인덱스가 Stages의 길이-1 보다 작으면 스테이지가 아직 안끝난것이므로 계속 진행한다.
Stages의 stageIndex번째 스테이지를 비활성화하고 index를 늘려준 뒤 그 index의 스테이지를 활성화해준다.
그리고 플레이어의 위치를 처음으로 초기화해준다.
그리고나서 UI의 스테이지 번호를 표시한다.
마지막 스테이지이면 Time.timeScale을 0으로 만들어 멈춘다.
이것을 0.5f를 하면 시간이 절반속도로 흐르고, 2로하면 2배 속도로 흐른다.
그리고 다시 시작하는 버튼인 UIRestartBtn이 보이게 활성화하고
btnText라는 객체를 만들어서 "Clear"이라고 텍스트를 수정한다.
VeiwBtn은 버튼이 활성화되는 함수이다.
누적포인트에 스테이지에서 획득한 점수를더해주고 , 스테이지포인트는 0으로만든다.
>피 깎기
public void HealthDown()
{
if (health > 1)
{
health--;
UIhealth[health].color = new Color(1, 0, 0, 0.2f);
}
else
{
//All health UI Off
UIhealth[0].color = new Color(1, 0, 0, 0.2f);
//player die effect
player.OnDie();
//retry button UI
Invoke("ViewBtn",3);
}
}
현재 피가 1보다 크면 health를 1 줄이고, UI에 있는 피를 까이게 해준다.
피가 깎이는 표현은 UI색깔을 빨갛게 해주고 투명도를 줄이면 된다.
현재 피가 1일때 피가 깎이면 처음 UI 색깔을 바꿔주고 OnDie함수를 실행한 뒤 버튼이 보이게 한다. 죽는 모션이 나온다.
>바닥에 떨어졌을때
void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.tag == "Player") {
//player Respawn
if(health > 1) {
PlayerReposition();
}
HealthDown();
}
}

바닥에 떨어졌을때 바로 죽게 하는 방법이다.
맨아래 초록색부분이 gameManager에 box collider2D를 적용한것이다.
플레이어라는 태그를 가진 캐릭터와 충돌이 발생할때이다.
피가 1보다 크면 캐릭터가 원점으로 돌아가게 한다.
그리고 피를 깎아준다.
>원점으로 재배치
void PlayerReposition()
{
player.transform.position = new Vector3(0, 0, -1);
player.VelocityZero();
}
VelocityZero는 PlayerMove에 선언을했는데
public void VelocityZero()
{
rigid.velocity = Vector2.zero;
}
아래의 zero 저부분은 0,0의 속도로 초기화하는것이다.
>다시 시작
public void Restart()
{
Time.timeScale=1;
SceneManager.LoadScene(0);
}
다시 timeScale을 1로 돌리고 처음 장면으로 설정을한다.
--------PlayerMove------
>Awake
void Awake()
{
rigid = GetComponent<Rigidbody2D>();
spriteRenderer = GetComponent<SpriteRenderer>();
anim=GetComponent<Animator>();
capsulecollider = GetComponent<CapsuleCollider2D>();
audioSource=GetComponent<AudioSource>();
}
초기화를 해준다.
>소리관련
void PlaySound(string action)
{
switch (action)
{
case "JUMP":
audioSource.clip= audioJump;
break;
case "ATTACK":
audioSource.clip= audioAttack;
break;
case "DAMAGED":
audioSource.clip= audioDamaged;
break;
case "ITEM":
audioSource.clip= audioItem;
break;
case "DIE":
audioSource.clip= audioDie;
break;
case "FINISH":
audioSource.clip= audioFinsh;
break;
}
audioSource.Play();
}
action이 뭐냐에 따라 다른 오디오 클립들이 사용된다.
> 소리 넣기
각 상황에 맞는 함수들 마지막에 PlaySound("JUMP");이런식으로 넣어준다.


