화면 가운데 플레이어, 오른쪽 위에는 HP 게이지를 표시한다. 화살이 위에서 아래로 떨어지고 플레이어를 좌우 화살표 버튼을 움직여 화살을 피한다. 플레이어가 화살에 맞으면 HP 게이지가 줄어든다.
이전 글 이어서 시작 !
[unity] #8. 화살 피하기 게임 - 1
- 화살 피하기 게임 화면 가운데 플레이어, 오른쪽 위에는 HP 게이지를 표시한다. 화살이 위에서 아래로 떨어지고 플레이어를 좌우 화살표 버튼을 움직여 화살을 피한다. 플레이어가 화살에 맞으
mingxoxo-record.tistory.com
- 프리팹과 공장 만들기
화살 오브젝트를 1초에 1개씩 만드는 공장(화살 제너레이터)을 만든다.
공장은 기계(제너레이터 스크립트)가 설계도(프리팹)대로 제품(인스턴스)를 생산하는 구조이다.
프리팹은 설계도와 비슷하다. 게임 중인 오브젝트를 만드는 데 필요한 정보가 쓰여 있고 프리팹이 있으면 몇 개라도 같은 오브젝트를 만들 수 있다. 같은 오브젝트를 많이 만들고 싶을 때 주로 프리팹을 사용한다.
프리팹을 사용하는 것과 단순한 복사는 차이가 있다.
예를 들어 흰색 화살 인스턴스를 10개 만든 후 화살 색을 빨간색으로 바꾸려고 하면 일일이 화살 10개의 색을 바꿔야 한다. 하지만 프리팹을 써서 복제했다면 프리팹 색만 바꿔도 화살 10개 모두 빨간색으로 바뀐다.
프리팹을 쓰면 변경사항이 있을 때 프리팹 파일만 수정하면 되므로 비교적 편하게 수정이 가능하다.
공장을 만드는 방법
1. 이미 있는 오브젝트를 사용해 프리팹을 만든다.
2. 제너레이터 스크립트를 만든다.
3. 빈 오브젝트에 제너레이터 스크립트를 적용한다.
4. 제너레이터 스크립트에 프리팹을 전달한다.
- 프리팹 만들기
설계도로 쓰고 싶은 오브젝트를 Hierarchy창에서 Project창으로 드래그&드롭 하면 된다.
프리팹을 만들면 씬에 배치한 화살 오브젝트는 필요가 없다. 따라서 Hierarchy창의 arrow를 삭제해준다.
(설계도가 있으면 제품은 언제든지 만들 수 있다.)
gif가 제대로 보이지 않으면 클릭하면 제대로 보인다 ㅠㅠ 왜그렇지..?
- 제너레이터 스크립트 작성 후 빈 오브젝트에 적용하기
프리팹을 만들었으므로 프리팹을 바탕으로 인스턴스를 만드는 제너레이터 스크립트를 만들 것이다.
Project창 오른쪽 마우스 클릭 --> Create --> C# script 선택 --> ArrowGenerator 로 이름 변경
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ArrowGenerator : MonoBehaviour
{
public GameObject arrowPrefab; //화살 설계도를 넣는 변수 선언
float span = 1.0f;
float delta = 0;
void Start()
{
}
void Update()
{
//Time.deltaTime --> 앞 프레임과 현재 프레임 사이의 시간 차이
//Instantiate --> 매개변수로 프리팹을 전달하면 반환값으로 프리팹 인스턴스를 돌려준다.
//as GameObject --> 기본적인 Object로 반환하는 것을 강제 형 변환(캐스트)를 통해 GameObject형으로 바꾼다.
this.delta += Time.deltaTime;
if (this.delta > this.span) //delat가 1초 이상이 되면
{
this.delta = 0;
GameObject go = Instantiate(arrowPrefab) as GameObject;
//화살의 x좌표를 -6부터 6 사이에 불규칙하게 위치하도록 랜덤으로 반환
int px = Random.Range(-6, 7);
go.transform.position = new Vector3(px, 7, 0);
}
}
}
빈 오브젝트에 제너레이터 스크립트를 적용해야 공장 오브젝트가 된다.
Hierarchy창 --> Create --> Create Empty --> ArrowGenerator 로 이름 변경
Project창의 ArrowGenerator 스크립트를 Hierarchy창의 ArrowGenerator 오브젝트로 드래그&드롭해준다.
- 제너레이터 스크립트에 프리팹 전달하기
앞에서 작성한 제너레이터 스크립트의 프리팹 변수와 프리팹의 실체를 연결해야 한다.
아웃렛 접속 --> 스크립트 내에 변수에 오브젝트 실체를 대입할 수 있게 한다.
아웃렛 접속
1. 스크립트 쪽에 콘센트 구멍을 만들어야 하므로 스크립트 변수 앞에 public 접근 수식자를 붙인다.
2. public 접근 수식자를 붙인 변수가 Inspector창에 보인다.
3. Inspector 창의 콘센트 구멍에 대입할 오브젝트를 끼운다.
아웃렛은 콘센트에서 플러그를 꽂는 구멍을 뜻한다.
아웃렛 접속에서는 스크립트 쪽에 플러그를 꽂을 수 있는 콘센트 구멍을 준비한다.
다음으로 Inspector 창에서 해당하는 플러그를 만들고 스크립트의 콘센트 구멍에 끼워 오브젝트를 대입한다.
ArrowGenerator에서 설계도를 나타내는 변수 arrowPrefab에 public 접근 수식자를 붙여 선언했다.
public GameObject arrowPrefab; //화살 설계도를 넣는 변수 선언
Project 창에 있는 arrowPrefab 을 Arrow Prefab 항목으로 드래그&드롭해 프리팹을 설정한다.
이렇게 하면 스크립트에서 선언한 arrowPrefab 변수에 프리팹 실체가 대입된다.
지금까지의 실행 결과
- UI 표시하고 갱신하는 감독 만들기
UI를 만드는 방법
1. UI 부품을 Scene뷰에 배치한다.
2. UI를 갱신하는 감독 스크립트를 작성한다.
3. 빈 오브젝트를 만들고 작성한 스크립트를 적용한다.
- 앵커 포인트 설정
화면 크기가 바뀌어도 화면 오른쪽 위에 HP 게이지가 표시되도록 앵커 포인트를 변경해준다.
앵커 포인트는 이름 그대로 닻을 내리는 장소를 뜻한다.
화면 크기가 바뀔 때 어디를 원점으로 해서 UI 부품 좌표를 다시 계산하는가? 이다.
UI 오브젝트의 위치는 앵커 포인트를 원점(0, 0)으로 하는 값으로 지정된다.
예를 들어 앵커 포인트를 화면 중앙에 두고 화면 크기를 줄이면 게이지 표시가 화면에서 이탈할 수 있다.
앵커 포인트를 화면 오른쪽 위에 두면 HP 게이지는 항상 오른쪽 위에 표시되고 화면에서 이탈하지 않는다.
앵커 포인트를 적절히 설정하면 실행하는 기기의 화면 크기에 의존하지 않는 UI를 만들 수 있다.
- HP 게이지 줄이기
HP 게이지를 줄이려면 UI 오브젝트의 Image에서 사용하는 Fill 기능을 사용한다.
Fill Amount 변수 값을 바꾸면 이미지 표시 영역을 줄이거나 늘릴 수 있다.
Fill Method 종류
- Horizontal : 가로 방향으로 이미지를 잘라낸다.
- Vertical : 세로 방향으로 이미지를 잘라낸다.
- Radial 90 : 90도 선형으로 이미지를 잘라낸다.
- Radial 180 : 반원형으로 이미지를 잘라낸다.
- Radial 360 : 원형으로 이미지를 잘라낸다.
실행 결과
- UI를 갱신하는 감독 오브젝트 만들기
감독 스크립트는 플레이어가 화살에 맞으면 이를 감지해 HP 게이지의 표시를 갱신한다.
1. 화살 컨트롤러는 감독에게 HP가 감소되었다고 알린다.
2. 감독은 HP게이지의 UI를 갱신한다.
감독 스크립트 작성
Project창 오른쪽 마우스 클릭 --> Create --> C# script 선택 --> GameDirector 로 이름 변경
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; //UI 오브젝트 스크립트 조작할 때 필요
public class GameDirector : MonoBehaviour
{
GameObject hpGauge;
void Start()
{
this.hpGauge = GameObject.Find("hpGauge");
}
public void DecreaseHp() //화살 컨트롤러에서 호출할 것이기 때문에 public으로 설정
{
this.hpGauge.GetComponent<Image>().fillAmount -= 0.1f;
}
}
Hierarchy 창에서 Create Empty를 선택해서 빈 오브젝트를 만든다.
감독 스크립트를 드래그앤 드랍으로 적용한다.
- HP가 줄었다고 감독에게 알리기
플레이어가 화살에 맞으면 화살 컨트롤러에서 감독 스크립트의 DecreaseHp 메서드 호출
자신 이외의 오브젝트 컴포넌트에 접근하는 방법
1. Find 메서드로 오브젝트를 찾는다.
2. GetComponent 메서드로 오브젝트의 컴포넌트를 구한다.
3. 컴포넌트를 가진 데이터에 접근한다.
ArrowController 스크립트에 아래의 코드를 추가한다.
if (d < r1 + r2) {
//감독 스크립트에 플레이어와 화살이 충돌했다고 전달
GameObject director = GameObject.Find("GameDirector");
director.GetComponent<GameDirector>().DecreaseHp();
//충돌한 경우 화살 소멸
Destroy(gameObject);
}
실행결과
: 플레이어가 화살에 맞을 때 마다 hpGauge가 줄어든다. 하지만 모두 줄어들고 HP가 0이 되어도 게임은 계속 진행된다.
나중에 게임 종료 or 클리어 화면으로 이동을 배우고 난 후 추가해야겠다.
- 스마트폰에서 움직이기
스마트폰에서는 좌우 키가 없기 때문에 스마트폰에서 조작할 수 있도록 화면에 좌우 버튼을 배치해준다.
1. UI를 사용해 오른쪽 버튼을 배치하고 설정한다.
2. 오른쪽 버튼을 복제해 왼쪽 버튼을 만든다.
3. 버튼에 반응해 플레이어가 움직이도록 스크립트를 수정한다.
버튼 이미지 위에는 레이블이 Button으로 표시되어 있다. 이 레이블은 Button 아래 Text라는 자식 요소가 관리한다. 여기서는 레이블이 필요하지 않으므로 이 Text를 삭제한다.
LButton도 RButton을 복사 붙여넣기 해준 후 수정한다.
위에서 작성한 PlayerController 스크립트를 수정해준다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
void Start()
{
}
public void LButtonDown() {
transform.Translate(-3, 0, 0); //왼쪽으로 3 이동
}
public void RButtonDown()
{
transform.Translate(3, 0, 0); //오른쪽으로 3 이동
}
}
- 버튼 눌렀을 때의 메서드 지정
이제 안드로이드 빌드 해주면 끝 !
빌드의 자세한 방법은 운세 룰렛 게시물의 아래쪽에 적혀있다.
[unity] #6. 운세 룰렛
게임 설계 단계 1. 화면에 놓일 오브젝트를 모두 나열한다. 2. 오브젝트를 움직일 수 있는 컨트롤러 스크립트를 정한다. 더보기 1단계에서 나열한 오브젝트 중에서 움직이는 오브젝트를 찾는다. �
mingxoxo-record.tistory.com
별 기능도 없는데 이렇게 많이 뭘 한다는게 신기하다 푸히히
출처 : <유니티 교과서 개정 3판> 책
'study > unity' 카테고리의 다른 글
[unity] #8. 화살 피하기 게임 - 1 (0) | 2020.08.20 |
---|---|
[unity] #7. 자동차 멈추기 게임 (0) | 2020.08.18 |
[unity] #6. 운세 룰렛 (2) | 2020.08.12 |
[unity] #5. C# 스크립트 기초 - 클래스, 벡터 (0) | 2020.08.09 |
[unity] #4. C# 스크립트 기초 - 배열, 함수 (0) | 2020.08.07 |