Unity/유니티 기본
[4.6] 화살 피하기 게임
ljw4104
2021. 4. 6. 12:37
1. 기본 화면 셋팅
* 고양이가 화면에서 보이지 않으면?
고양이의 Component 중에서 Sprite Renderer의 Order in Layer를 1로 해준다. 그러면 백그라운드 앞에 고양이게 위치하게 된다.
2. 기본적인 Player의 움직임 작성 (PlayerController.cs)
PlayerController.cs
using UnityEngine;
public class PlayerController : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
//해당 키가 눌린 순간
if (Input.GetKeyDown(KeyCode.LeftArrow))
{
transform.Translate(-3, 0, 0);
}
if (Input.GetKeyDown(KeyCode.RightArrow))
{
transform.Translate(3, 0, 0);
}
}
}
메서드 | 동작 |
GetKeyDown(Keycode key) | key가 눌렸을 때 |
GetKey(Keycode key) | key가 눌리는 동안 |
GetKeyUp(Keycode key) | key가 눌렸다가 뗐을 때 |
3. 화살 떨어트리기 ( Physics 사용 X )
using UnityEngine;
public class ArrowController : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
transform.Translate(0, -0.1f, 0); //프레임마다 등속운동으로 내려온다.
if(transform.position.y < -4.33f)
{
Destroy(gameObject); //화면 밖으로 나간 오브젝트를 파괴함.
}
}
}
- void UnityEngine.Object.Destroy : 게임오브젝트, 컴포넌트나 에셋을 삭제한다.
4. 화살이 고양이에 닿이면 삭제
using UnityEngine;
public class ArrowController : MonoBehaviour
{
private GameObject player;
// Start is called before the first frame update
void Start()
{
this.player = GameObject.Find("player");
}
// Update is called once per frame
void Update()
{
transform.Translate(0, -0.1f, 0); //프레임마다 등속운동으로 내려온다.
if (transform.position.y < -4.33f)
{
Destroy(gameObject); //화면 밖으로 나간 오브젝트를 파괴함.
}
//충돌판정
Vector2 p1 = transform.position; //화살의 중심좌표
Vector2 p2 = this.player.transform.position; //유저의 중심좌표
Vector2 dir = p1 - p2; //화살~유저 사이의 방향벡터
float d = dir.magnitude; //방향벡터의 스칼라(크기)
float r1 = 0.5f; //화살의 반경
float r2 = 1.0f; //플레이어의 반경
if (d < r1 + r2)
{
//벡터의 크기가 화살의 반경과 플레이어의 반경의 합과 겹친다면 충돌했다고 판정함.
Destroy(gameObject);
}
}
}
4. 화살 프리팹 만들기
4-1. 프리팹 ( Prefab )
- Hierarchy = 게임오브젝트 / Project = 파일
- 게임오브젝트의 파일화 ( Hierarchy의 게임오브젝트를 Project 쪽으로 끌고 오면 만들어짐 )
- 화살같이 같은 오브젝트를 무한히 만들려고 할 때 사용함.
- 하나 수정하면 다른 것도 수정이 된다. 즉, 각각의 것은 링크되어있다. 하지만 Hierarchy에 나와있는 것을 수정하면 그것만 수정이된다.
4-2. Prefab 생성
public GameObject 프리팹이름;
GameObject 이름 = Instantiate<GameObject>(프리팹이름);
//or = Instantiate(프리팹이름) as GameObject;
이름.transform.position = new Vector3(px, 7, 0);
5. HP바 넣기
1. Image 삽입
- 메뉴 GameObject -> UI -> Image 로 삽입
- Source Image에 hp_gauge Sprite Image 삽입
1-1. Canvas 설정
Reference Resolution을 항상 설정해야됨.
1-2. Anchor 설정
- 좌표로 UI의 position을 설정하면 기기마다 값이 다를 수 있다. 그러므로 Anchor로 어느 기기든 똑같은 위치에 나타나도록 해야한다.
2. HP 게이지 줄여나가기
- Image 컴포넌트의 Image Type 속성을 simple에서 Filled로 바꿈.
- Fill Method : Radial 360, Fill Origin : Top
- Fill Amount를 코드로 줄여나갈 수 있다. ( 손으로 할 수 있는건 코드로 치환이 가능하다. )
using UnityEngine;
using UnityEngine.UI;
public class GameDirector : MonoBehaviour
{
private GameObject hpGauge;
// Start is called before the first frame update
void Start()
{
hpGauge = GameObject.Find("hpGauge");
}
public void DecreaseHp()
{
this.hpGauge.GetComponent<Image>().fillAmount -= 0.1f;
}
}
3. 충돌 했을 때 DecreaseHp() 호출하도록 하기
using UnityEngine;
public class ArrowController : MonoBehaviour
{
public float arrowSpeed = -0.07f;
private GameObject player;
// Start is called before the first frame update
void Start()
{
this.player = GameObject.Find("player");
}
// Update is called once per frame
void Update()
{
transform.Translate(0, this.arrowSpeed, 0); //프레임마다 등속운동으로 내려온다.
if (transform.position.y < -4.33f)
{
Destroy(gameObject); //화면 밖으로 나간 오브젝트를 파괴함.
}
//충돌판정
Vector2 p1 = transform.position; //화살의 중심좌표
Vector2 p2 = this.player.transform.position; //유저의 중심좌표
Vector2 dir = p1 - p2; //화살~유저 사이의 방향벡터
float d = dir.magnitude; //방향벡터의 스칼라(크기)
float r1 = 0.5f; //화살의 반경
float r2 = 1.0f; //플레이어의 반경
if (d < r1 + r2)
{
//감독 스크립트에 플레이어와 화살이 충돌했다고 전달함.
GameObject directorGo = GameObject.Find("GameDirector");
directorGo.GetComponent<GameDirector>().DecreaseHp();
//벡터의 크기가 화살의 반경과 플레이어의 반경의 합과 겹친다면 충돌했다고 판정함.
Destroy(gameObject);
}
}
}
5. 버튼으로 캐릭터 조작하기
- Canvas를 UIGame으로 이름을 변경하고, UIGame 스크립트를 새로 만들어 부착
- UI -> Button 2개를 생성 후 Anchor 설정.
Button에 Event 다는 방법
- 위에서 만든 UIGame 스크립트를 연다.
- 스크립트에서 처리할 UI를 변수로 선언 후 불러온다.
- AddListener 이벤트에 델리게이트로 달아주면 된다.
- 버튼이 조작되었을때, 캐릭터가 움직이게 하는 것은 이 Scene의 모든 것을 담당하는 InGame이라는 스크립트를 새로 만들어 거기서 관리한다.
- 캐릭터 컨트롤러에는 캐릭터에 관련된 것만, UI에 관련된 것은 UI만 관리하도록 하기 위해서이다.
InGame.cs
using UnityEngine;
using UnityEngine.UI;
public class InGame : MonoBehaviour
{
public PlayerController controller;
public UIGame uiGame;
// Start is called before the first frame update
void Start()
{
this.uiGame.lBtn.onClick.AddListener(() =>
{
controller.Move(Vector2.left);
});
this.uiGame.rBtn.onClick.AddListener(() =>
{
controller.Move(Vector2.right);
});
}
// Update is called once per frame
void Update()
{
}
}
public void Move(Vector2 dir)
{
transform.Translate(dir.x * 3, 0, 0);
}