일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 유니티 GUI
- 드래곤 플라이트
- 앱 배포
- Photon Fusion
- 드래곤 플라이트 모작
- 유니티 UI
- XR
- VR
- 유니티
- 유니티 Json 데이터 연동
- 오큘러스
- 모작
- 길건너 친구들
- meta xr
- 개발일지
- Oculus
- 팀 프로젝트
- 포트폴리오
- OVR
- meta
- 연습
- ChatGPT
- 멀티플레이
- HAPTIC
- 팀프로젝트
- 개발
- 오브젝트 풀링
- 가상현실
- CGV
- input system
- Today
- Total
EasyCastleUNITY
고양이 화살 피하기 게임 본문
전체 화면
---게임의 간단한 개요---
이동버튼을 누르면 그 방향으로 플레이어가 이동합니다. (PC에서는 화면 클릭과 키보드를 통해 움직일 수 있습니다.)
플레이어 캐릭터의 체력은 총 10으로, 화살에 부딫칠때마다, 체력이 1씩 감소합니다.
점수는 화살이 바닥에 닿으면 올라가며, 이때마다 100씩 증가합니다.
플레이어 캐릭터의 체력이 0이 되면, Game Over라는 문구가 나오며 게임이 종료됩니다.
점수는 더 이상 올라가지 않으며, 플레이어 또한 움직이지 않습니다.
---제작 과정에서의 주의한 점---
1.플레이어가 버튼을 계속 누르면, 캐릭터가 렌더링 영역 밖으로 나가는 문제가 있었다.
이러한 문제를 Mathf.Clamp라는 메서드를 통해 해결했다.
이 블로그를 참고 했다.
이런 식으로 메서드를 만들어 캐릭터가 움직일 수 있는 영역을 제한시켰다.
2. 게임 오버가 되었지만 캐릭터가 움직이는 문제
각각의 이동버튼은 CatController의 MoveLeft(), MoveRight() 라는 메서드와 연결되어 있다.
그렇기에 이 2개의 메서드 자체의 제한 조건을 걸어, 게임이 종료되면 이 함수가 동작할 수 없도록 만들었다.
3. 게임이 종료되었지만, 점수를 계속 얻는 문제점
앞에 2번 처럼 똑같이 제한을 걸어, 게임이 종료되면 동작하지 않도록 하였다.
ArrowController에서의 cat은 CatController의 instance를 의미한다.
4. 게임 오버 시, 이미 생성된 화살이 그대로 존재하는 문제
3번과 같이 엮여 있는 문제였는데, 화살이 그대로 존재하기에 바닥에 내려와서 점수를 계산하면서
3번 문제가 생긴 것이었다. 그래서 게임이 종료되면 모든 화살들을 삭제하는 방식으로 해결 하였다.
---전체적인 코드---
CatController: 캐릭터의 이동을 담당하는 클래스
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CatController : MonoBehaviour
{
public float radius = 1;
public int hp = 10;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
this.transform.position = ClampPosition(this.transform.position);
//키 입력받기
if (Input.GetKeyDown(KeyCode.LeftArrow))
{
//왼쪽 화살표 누르면 -3이동
this.MoveLeft();
}
else if (Input.GetKeyDown(KeyCode.RightArrow))
{
//오른쪽 화살표 누르면 +3이동
this.MoveRight();
}
}
public void MoveLeft()
{
if (this.hp > 0)
{
this.transform.Translate(-3.0f, 0, 0); //-3씩 이동 좌표 -9~9로 제한
}
}
public void MoveRight()
{
if (this.hp > 0)
{
this.transform.Translate(3.0f, 0, 0); //3씩 이동 좌표 -9~9로 제한
}
}
public Vector3 ClampPosition(Vector3 position)
{
return new Vector3(Mathf.Clamp(position.x, -9.0f, 9.0f), -3.4f, 0);
}
//이벤트 함수
private void OnDrawGizmos()
{
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(this.transform.position, this.radius);
}
}
ArrowController: 화살의 움직임과, 캐릭터와의 충돌, 화살의 삭제등을 담당하는 클래스
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ArrowController : MonoBehaviour
{
[SerializeField] //이 애트리뷰트를 사용하면 private 멤버도 인스펙터에 노출
private float speed;
private GameObject catGo;
private GameObject gameDirectorGo;
GameDirector gameDirector;
private CatController cat;
public int score=0;
// Start is called before the first frame update
void Start()
{
this.catGo = GameObject.Find("cat");
cat = this.catGo.GetComponent<CatController>();
this.gameDirectorGo = GameObject.Find("GameDirector");
this.gameDirector = this.gameDirectorGo.GetComponent<GameDirector>();
Debug.Log("catGo:{0}", this.catGo);
}
private bool isCollide()
{
//두 원사이의 거리, 정확히는 화살의 중점과 고양이의 중점 사이의 거리
float distance = Vector3.Distance(this.transform.position, this.catGo.transform.position);
//반지름의 합
CatController catController = this.catGo.GetComponent<CatController>();
float sumRadius = this.radius + catController.radius;
// Debug.LogFormat("sumRadius:{0}", sumRadius);
//두 원사이의 거리가 반지름의 합보다 크면 부딪히지 않음 (false)
//두 원의 반지름의 합이 두 원사이의 거리보다 크다면 부딪혔다.
return distance < sumRadius;
}
// Update is called once per frame
void Update()
{
//프레임 기반
//this.gameObject.transform.Translate(0, -1, 0);
//시간 기반 이동
//속도 * 방향 * 시간
//if * new Vector3(0,-1,0) * Time.deltaTime
this.gameObject.transform.Translate(this.speed * Vector3.down * Time.deltaTime);
if(this.transform.position.y <= -3.9f) //화살이 바닥에 있을 때
{
if(cat.hp > 0) //게임 진행중
{
gameDirector.score += 100;
}
Destroy(this.gameObject);
}
if(this.isCollide()) //충돌판단
{
// Debug.LogFormat("충돌했다");
GameObject gameDirectorGo=GameObject.Find("GameDirector");
GameDirector gameDirector =gameDirectorGo.GetComponent<GameDirector>();
gameDirector.DecreseHp();
//ArrowController 컴포넌트가 붙어있는 게임오브젝트를 씬에서 제거한다
Destroy(this.gameObject);
}
else
{
// Debug.LogFormat("충돌하지 않았다");
}
//게임이 종료되면 이미 생성되어 있던 화살도 전부 삭제
if(cat.hp <= 0)
{
Destroy(this.gameObject);
}
}
public float radius = 1;
//이벤트 함수
private void OnDrawGizmos()
{
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(this.transform.position, this.radius);
}
}
ArrowGenerator: 프리팹화된 화살을 생성(랜덤한 위치에 생성) 하는 역할을 하는 클래스
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ArrowGenerator : MonoBehaviour
{
public GameObject arrowPrefab; //프리팹 원본 파일
private float elapsedTime; //경과시간 //Time.deltaTime을 어딘가에다가 누적: 흘러간 시간
private GameObject catGo;
private CatController cat;
// Start is called before the first frame update
void Start()
{
this.catGo = GameObject.Find("cat");
cat = this.catGo.GetComponent<CatController>();
}
// Update is called once per frame
void Update()
{
//매프레임 마다 Time.deltaTime을 경과시간에 더해준다.
this.elapsedTime += Time.deltaTime;
//경과시간이 1초를 지나갔다면
if (this.elapsedTime > 1f && cat.hp > 0)
{
//화살을 만든다
this.CreateArrow();
this.elapsedTime = 0f; //다시 처음부터 누적하도록 초기화
}
}
private void CreateArrow()
{
//arrowGo: 프리팹 복제본(인스턴스)
GameObject arrowGo = Instantiate(this.arrowPrefab);
arrowGo.transform.position = new Vector3(Random.Range(-9, 10), 6f, 0);
}
}
GameDirector: UI등 게임의 기능을 전체적으로 통괄하는 클래스
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GameDirector : MonoBehaviour
{
private GameObject catGo;
private GameObject hpGaugeGo;
private GameObject scoreGo; //UI Text
private GameObject gameStateGo; //UI Text
private CatController cat;
public int score;
private int hp;
// Start is called before the first frame update
void Start()
{
this.catGo=GameObject.Find("cat");
this.hpGaugeGo=GameObject.Find("hpGauge");
this.scoreGo = GameObject.Find("ScoreText");
this.gameStateGo = GameObject.Find("GameState");
cat = this.catGo.GetComponent<CatController>();
Debug.LogFormat("this.catGo:{0} this.hpGauge:{1}",this.catGo,this.hpGaugeGo);
}
void Update()
{
this.hp = cat.hp;
Text scoreText = this.scoreGo.GetComponent<Text>();
scoreText.text = string.Format("{0}", score);
if (this.hp == 0)
{
Text gameStateText = this.gameStateGo.GetComponent<Text>();
gameStateText.text = "Game over";
}
}
//체력 감소
public void DecreseHp()
{
Image hpGauge = this.hpGaugeGo.GetComponent<Image>();
hpGauge.fillAmount -= 0.1f; //10%씩 감소
cat.hp--;
}
}
결과
'유니티 기초' 카테고리의 다른 글
유니티 밤송이 던지기 (0) | 2023.08.04 |
---|---|
구름 오르기 (0) | 2023.08.02 |
2023/08/01 복습 (0) | 2023.08.01 |
Swipe car 음향 및 UI 추가 (0) | 2023.08.01 |
간단 룰렛 (0) | 2023.08.01 |