지우너
[Unity 3D Run] 게임오버/클리어 UI (3) 본문
03.23-03.24
월요일 취업 상담이 끝나고 카페에서 4시쯤까지 공부한 이후로, 유니티를 거의 만지지 않았다…
스크립트를 만드는 게 생각보다 어렵다고 생각이 들어서 자꾸 회피하게 됐는데, 그래도 오늘은 공부를 해야 할 것 같아서 잠깐이나마 할 수 있는 것들을 손봤다.
Goal 오브젝트 만들기
큐브 오브젝트 생성 > is Trigger 체크 > Goal Material 생성&적용
Goal Material은 살짝 투명한 녹색으로 만들어 닿으면 GameClear 판정
투명도 값을 조정해줘도 투명하게 설정되지 않았다.
Shader가 Standard로 설정되어 있는데 이를 클릭하여
Legacy Shaders→Transparent→Diffuse 선택
Goal 스크립트 - OnTriggerEnter(Collider col)
게임 클리어를 판단할 오브젝트도 생성했으니, 여기에 접촉했을 때 클리어 판정이 되도록 스크립트를 만들면 된다.
Obstacle은 장애물이라서 Trigger 체크를 안 하고(부딪혀서 없어지는 느낌이니까), OnCollisionEnter 함수를 사용했다.
Goal은 결승지점을 통과하는 느낌이라서, 부딪히면 안 되기 때문에 Trigger로 설정했다. 따라서 함수도 OnCollisionEnter가 아니라. OnTriggerEnter함수를 사용했다.
💡 유니티 2D 게임 제작 p118
OnTriggerEnter2D(Collider2D collision) OnTriggerEnter2D메서드는 Collider에 무엇인가 닿으면 호출되는 메서드이다. 인수의 collision이 접촉한 Collider 컴포넌트이며, collision이 가진 gameobject 변수가 ‘Collider컴포넌트가 어태치된 게임 오브젝트’이다.
OnTriggerEnter2D / OnTriggerStay2D / OnTriggerExit2D 와 같은 충돌 판정 메서드가 있는데, 이들은 Is Trigger를 체크해둔 콜라이더가 다른 콜라이더와 접촉했거나, 접촉 중이거나, 접촉이 끝났을 때 호출되는 메서드이다. 인수의 collision 변수는 접촉한 콜라이더 컴포넌트이다.
RESTART / QUIT 버튼
RESTART 버튼을 Canvas에 연결된 GameUI 스크립트의 OnClick_Restart 함수와 연결
QUIT 버튼을 Canvas에 연결된 GameUI 스크립트의 OnClick_Quit 함수와 연결
// Player.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// GetComponent<PlayerController>()는 PlayerController와 Player 스크립트가 같은 오브젝트에 붙어 있는걸 전제로 한다.
// [RequireComponent(typeof(PlayerController))] 코드를 적어줘서 이 부분이 에러를 내지 않게 됨.
[RequireComponent(typeof(PlayerController))]
public class Player : MonoBehaviour
{
public enum State { playing, gameclear, gameover };
State currentState;
public float moveSpeed = 3.0f;
protected bool dead;
// moveVelocity를 다른 스크립트인 PlayerController로 전달해서 물리적인 부분들을 처리할 수 있도록 할 것
// 그래서 PlayerController에 대한 레퍼런스를 가져와야합니다.
PlayerController controller;
public GameManager manager;
void Start()
{
currentState = State.playing;
}
void Awake()
{
controller = GetComponent<PlayerController>();
}
void Update()
{
if (currentState==State.playing)
{
// Movement input 플레이어의 움직임을 입력 받는 것
// 수평(Horizontal) 과 수직(Vertical) 방향에 대한 입력을 받고 싶으니
// Input. 을 적고 GetAxis()를 호출해서 "Horizontal"을 넣습니다.
// y값은 내버려 둬도 되며(0), 일정한 속도로 앞으로 가도록 moveSpeed를 넣어줬다.
Vector3 moveInput = new Vector3(Input.GetAxisRaw("Horizontal") * moveSpeed, 0, moveSpeed);
// 입력 받은 값을 방향으로 변환하고 움직임 속도를 곱할 겁니다.
// 입력의 방향을 얻기 위해 moveInput를 정규화(nomalized)하여 가져옵니다 (nomarlized는 방향을 가리키는 단위벡터로 만드는 연산)
// 거기에 moveSpeed를 곱해줍니다
Vector3 moveVelocity = moveInput.normalized * moveSpeed;
// controller에게 velocity값을 넘겨줌
controller.Move(moveVelocity);
}
}
public void Clear()
{
currentState = State.gameclear;
GameObject.Destroy(gameObject);
}
public void Die()
{
// 죽었으니까 dead를 true로 변경
dead = true;
currentState = State.gameover;
// 게임 매니저의 GameOver함수 호출
manager.GameOver();
// 플레이어 오브젝트를 삭제
GameObject.Destroy(gameObject);
}
}
// GameManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GameManager : MonoBehaviour
{
// +++ 변수 선언 +++
public GameObject gameEndPanel;
public Text gameStateText;
public GameObject restartButton;
public GameObject nextButton;
// 플레이어를 스크립트로 가져오기
public Player player;
// RESTART 버튼이 눌리면
public void GameStart()
{
//gameEnd UI가 안 보이게 설정
gameEndPanel.SetActive(false);
// 현재 씬(=현재 스테이지) 다시 시작
}
public void GameOver()
{
// 텍스트가 기본적으로 GameOver로 설정되어 있다.
// gameStateText.text = "GameOver!";
// next 버튼 비활성화 Restart 버튼 활성
nextButton.SetActive(false);
restartButton.SetActive(true);
gameEndPanel.SetActive(true);
}
public void GameClear()
{
gameStateText.text = "GameClear!";
// next 버튼 활성화 Restart 버튼 비활성화
restartButton.SetActive(false);
nextButton.SetActive(true);
gameEndPanel.SetActive(true);
}
}
// GameUI.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; // UI를 사용할 때 필요
using UnityEngine.SceneManagement;
public class GameUI : MonoBehaviour
{
public GameObject GameEnd;
public GameObject GameState;// 게임 상태를 표시하는 오브젝트
private Text text; // GameOver!/GameClear!를 표시
public GameObject RestartButton;
public GameObject QuitButton;
// 현재 씬 이름 (RESTRAT를 위/)
public string sceneName;
public string nextScene;
// Start is called before the first frame update
void Start()
{
text = GameState.GetComponent<Text>();
GameEnd.SetActive(false); // 패널숨기기
}
// Update is called once per frame
void Update()
{
}
// UI Input
// RESTART 버튼을 눌렀을 때 현재 씬 다시 시작
public void OnClick_Restart()
{
SceneManager.LoadScene(sceneName);
}
// QUIT버튼을 누르면 스테이지 선택창으로 돌아가도록 만들기
public void OnClick_Quit()
{
// 스테이지 선택 씬을 아직 만들지 않았으므로 주석처리
// SceneManager.LoadScene("Menu");
}
// 게임을 클리어하면 Restart 버튼이 비활성화 되고
// 다음 스테이지로 갈 수 있는 Next 버튼이 활성화 된다.
public void OnClick_Next()
{
SceneManager.LoadScene(nextScene);
}
}
// Obstacle.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Obstacle : MonoBehaviour
{
GameObject target;
private Player player;
void Start()
{
target = GameObject.FindGameObjectWithTag("Player");
player = target.GetComponent<Player>();
}
void Update()
{
}
void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.tag == "Player")
{
// 플레이어가 접촉했다면 플레이어Die(GameOver, Camera Stop)
player.Die();
}
}
}
// Goal.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Goal : MonoBehaviour
{
GameObject target;
private Player player;
public GameManager manager;
void Start()
{
target = GameObject.FindGameObjectWithTag("Player");
player = target.GetComponent<Player>();
}
void Update()
{
}
void OnTriggerEnter(Collider collision)
{
if (collision.gameObject.tag == "Player")
{
// 플레이어 오브젝트가 Goal 오브젝트에 닿으면 게임매니저의 GameClear 호출
manager.GameClear();
player.Clear();
}
}
}
그리고 스크립트를 어태치한 각 오브젝트 인스펙터의 변수에 해당하는 오브젝트들을 끌어다 넣었더니, 제대로 작동했다!
그리고 플레이어가 서 있는 땅을 Plane에서 Quad로 변경해주었다.
이건 오브젝트 투명도 조절을 보다가 해당 블로그의 최신글이라 보게 된 글이다.
Quad가 폴리곤을 더 적게 사용하여 성능적인 부하가 적다고 한다. 단, Quad는 2D 기반이라 3D에서 사용할 때는 x축 회전이 필요하다.
http://answers.unity3d.com/questions/139900/what-is-the-difference-between-a-quad-and-a-plane.html
he built-in plane has 121 vertices and 200 triangles, and a quad has 4 vertices and 2 triangles. As for the shader,
현재까지 진행한 부분의 동영상이다. 아래 베이스를 바탕으로 여러 개의 스테이지를 구성할 것이다.
(아직 여러 스테이지를 만들지 않았고, 베이스라서 일단 NEXT를 누르면 재시작 되게 만들었다)
앞으로 해야 할 것
캐릭터의 점프 구현
타이틀 화면(게임시작, 옵션, 게임 종료 버튼)
스테이지 선택 화면
사운드
있으면 좋겠다 싶은 기능
캐릭터 모양 선택(캡슐, 큐브, 구 등)
사망 애니메이션(죽으면 부서지는 것 같은 느낌으로)
'Project' 카테고리의 다른 글
[Unity 3D Run] (아직 못함) 캐릭터를 가리는 오브젝트의 투명도 처리 (0) | 2023.05.27 |
---|---|
[Unity 3D Run] 해상도 설정 (0) | 2023.04.08 |
[Unity 3D Run] 게임오버 UI (2) 공부+약간 수정 (0) | 2023.03.21 |
[Unity 3D Run] 게임 오버 UI(1) (0) | 2023.03.16 |
[Unity 3D Run] 장애물 충돌 설정 (0) | 2023.03.13 |