바닷속에서 장애물을 피하며 골인지점에 무사히 도착하면 클리어하는 게임 플레이 화면을 만들기 위해서 가장 첫 단계로 플레이어가 y축을 따가 위, 아래로 이동하는 코드를 작성하였다. 우리 게임은 모바일 게임으로 기획하였기 때문에 버튼 UI를 배치시키고 버튼을 누르면 이에 반응하여 플레이어가 이동하도록 코드를 작성하였다.
플레이어의 움직임을 구현하기 위해서 두 개의 스크립트를 작성하였다.
PlayerController
ButtonEvent
Player 오브젝트
일단 플레이어 역할을 할 오브젝트를 하나 만들었다. 아직 캐릭터 디자인이 진행중이어서 임시로 캡슐모양의 3D 오브젝트를 사용하였다. 플레이어 움직임과 기타 제어 사항들을 작성할 PlayerController 스크립트를 만들고 오브젝트에 컴포넌트로 추가해주었다.
Button UI
모바일 게임이므로 터치할 버튼 UI를 배치하여야 한다. 오른쪽에 위, 아래로 이동할 수 있는 UpButton, DownButton 2개를 배치하고 왼쪽에는 Dash 버튼을 배치하였다. UpButton이나 DownButton과 Dash버튼을 함께 누르면 이동속도가 2배로 증가한다.
오른쪽에 위치한 UpButton, DownButton의 앵커를 right-botton으로 설정하였다. 마찬가지로 왼쪽에 위치한 Dash 버튼의 앵커를 left-bottom으로 설정하였다.
여기까지 플레이어 이동에 필요한 오브젝트는 모두 배치하였다.
PlayerController 스크립트
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
// 이동 상태
public bool upMove = false;
public bool downMove = false;
public bool dash = false;
// 한번에 이동할 Y값
private Vector3 moveY = new Vector3(0, 3, 0);
private void Update() {
// Up 버튼을 누른 상태
if (upMove)
{
transform.Translate(moveY * Time.deltaTime); // 이동
if (dash) {
transform.Translate(moveY * 2* Time.deltaTime); // 2배의 속도로 이동
}
}
// Down 버튼을 누른 상태
if (downMove) {
transform.Translate(-moveY * Time.deltaTime); // 이동
if (dash) {
transform.Translate(-moveY * 2* Time.deltaTime); // 2배의 속도로 이동
}
}
}
}
public bool upMove = false;
public bool downMove = false;
public bool dash = false;
현재 플레이어의 이동 상태를 나타내는 bool형 변수 3개를 만들었다. 버튼을 누르면 플레이어가 이동하는 것이기 때문에, 버튼이 눌려진 상태인지 아닌지 알아야할 필요가 있다. 이 변수 3개는 버튼이 눌려졌는지 그 상태를 나타내는 변수이다. 또한 Update() 함수에서 현재 상태에 따라 플레이어가 이동하는 코드를 작성하기 위하여 이 변수들이 필요했다.
private Vector3 moveY = new Vector3(0, 3, 0);
우리 게임에서 플레이어의 x좌표는 일정한 값으로 고정되어있고, 플레이어는 y축으로만 이동하여 장애물을 피한다. 버튼을 눌렀을 때, 정해진 속도로 이동하므로 Vector값을 변수로 미리 만들어두었다.
private void Update() {
// Up 버튼을 누른 상태
if (upMove)
{
transform.Translate(moveY * Time.deltaTime); // 이동
if (dash) {
transform.Translate(moveY * 2* Time.deltaTime); // 2배의 속도로 이동
}
}
// Down 버튼을 누른 상태
if (downMove) {
transform.Translate(-moveY * Time.deltaTime); // 이동
if (dash) {
transform.Translate(-moveY * 2* Time.deltaTime); // 2배의 속도로 이동
}
}
}
Update() 함수 내부에서 조건문을 사용하여 upMove가 true일 경우, 즉 UpButton을 눌렀을 경우에 플레이어가 moveY만큼 이동하도록 하였다. 기기마다의 차이를 줄이기 위해 Time.deltaTime을 곱해주었다. UpButton을 누름과 동시에 Dash 버튼을 누른다면 이동 속도가 2배가 되도록 하였다. downMove가 true일 경우도 똑같은 코드에 -moveY만큼 이동되도록 하였다.
ButtonEvent 스크립트
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class ButtonEvent : MonoBehaviour
{
GameObject Player; // 플레이어 오브젝트 할당
PlayerController playerController;
void Start() {
// 초기화
Player = GameObject.Find("Player");
playerController = Player.GetComponent<PlayerController>();
}
// 버튼을 누르면 플레이어가 위로 올라감
public void UP_pointerDown() {
playerController.upMove = true;
}
// 버튼을 떼면 플레이어 움직임이 멈춤
public void UP_pointerUp() {
playerController.upMove = false;
}
// 버튼을 누르면 플레이어가 아래로 내려감
public void DOWN_pointerDown() {
playerController.downMove = true;
}
public void DOWN_pointerUp() {
playerController.downMove = false;
}
public void DASH_pointerDown() {
playerController.dash = true;
}
public void DASH_pointerUp() {
playerController.dash = false;
}
}
ButtonEvent 코드는 버튼을 눌렀을 때, 버튼을 떼었을 때의 동작을 적어주었다. PlayerController 코드의 upMove, downMove, dash 변수를 버튼을 눌렀다면 true로, 버튼을 떼었다면 false로 변경하도록 코드를 작성하였다.
GameObject Player; // 플레이어 오브젝트 할당
PlayerController playerController;
void Start() {
// 초기화
Player = GameObject.Find("Player");
playerController = Player.GetComponent<PlayerController>();
}
Player 오브젝트가 가지고 있는 PlayerController 컴포넌트를 PlayerController 객체에 할당하였다. 이를 통해 플레이어의 PlayerController 컴포넌트에 쉽게 접근할 수 있다.
// 버튼을 누르면 플레이어가 위로 올라감
public void UP_pointerDown() {
playerController.upMove = true;
}
// 버튼을 떼면 플레이어 움직임이 멈춤
public void UP_pointerUp() {
playerController.upMove = false;
}
UpButton 버튼을 눌렀을 때 실행되는 함수로 Up_pointerDown()함수를, 버튼을 떼었을 때 실행되는 함수로 Up_pointerUp() 함수를 정의하였다. 이 함수는 나중에 인스펙터창에서 적용시킨다. 버튼을 누를때마다 PlayerController.upMove의 값이 바뀐다. ButtonEvent 스크립트에서 upMove가 true가 되면, PlayerController 스크립트의 Update() 함수 내부 조건문의 조건을 만족하게 되어 플레이어가 이동하는 코드가 실행된다.
ButtonEvent 스크립트 적용
유니티 화면으로 돌아와 버튼의 인스펙터창에서 ButtonEvent 스크립트를 추가한다. AddComponent로 EventTrigger 컴포넌트를 추가한다. 하단 Add New Event Type을 누르면 어떤 이벤트를 처리할지 나오는데, PointerDown과 PointerUp을 선택한다. PointerDown은 버튼을 눌렀을 때, PointerUp은 버튼을 떼었을 때 어떤 처리를 할지 정할 수 있다. 적용할 오브젝트를 UpButton으로 선택해준 다음, 어떤 함수를 적용시킬지 고른다.
ButtonEvent 스크립트에서 작성했던 UP_PointerDown() 함수를 선택하면 UpButton 버튼을 눌렀을 때 해당 함수가 실행된다. 나머지 버튼들도 똑같이 작업해주면 된다.
인스펙터창에서 추가한 EventTrigger의 이벤트인 PointerDown와 PointerUp에서 이벤트 처리 함수를 지정한 과정은 IPointerDownHandler, IPointerUpHandlder 인터페이스 의 매소드를 구현한 것과 같다고 볼 수 있다.