이번 장에서는 소코반 게임의 플레이어 조작 기능을 구현할 것이다. 플레이어의 이동과 관련된 코드와 컴포넌트를 다룰 예정이다.
Unity에서는 두 가지 주요 함수를 사용하여 게임의 로직을 제어한다.
Start()
: 이 함수는 게임 오브젝트가 처음 활성화될 때 한 번만 호출된다. 변수의 초기화나 게임 시작 시 한 번만 수행해야 할 로직을 넣는다. 예를 들어, 플레이어의 초기 위치나 점수를 설정하는 등의 작업이 이 함수 안에 들어간다.void Start()
{
// 초기 위치 설정
transform.position = new Vector3(0, 0, 0);
}
Update()
: 이 함수는 매 프레임마다 호출되며, 게임의 주 로직이 들어간다. 플레이어의 이동, 적의 생성, 시간 관리 등 게임 상태를 지속적으로 업데이트하는 데 사용된다.void Update()
{
// 플레이어의 이동 로직
}
Unity에서 플레이어의 키보드 입력은 주로 Update() 함수 내에서 처리된다. 다음은 플레이어의 이동을 WASD 키로 조작하는 기본적인 방법을 보여준다.
Input.GetKey
: 특정 키가 눌러져 있는 동안 true
를 반환한다. 이를 통해 눌린 키에 따라 플레이어에 힘을 가하거나 방향을 바꾼다.void Update()
{
if(Input.GetKey(KeyCode.W))
playerRigidbody.AddForce(0, 0, speed); // W 키를 누르면 z축 방향으로 이동
if(Input.GetKey(KeyCode.A))
playerRigidbody.AddForce(-speed, 0, 0); // A 키를 누르면 x축 방향으로 음수 방향으로 이동
if(Input.GetKey(KeyCode.S))
playerRigidbody.AddForce(0, 0, -speed); // S 키를 누르면 z축 방향으로 음수 방향으로 이동
if(Input.GetKey(KeyCode.D))
playerRigidbody.AddForce(speed, 0, 0); // D 키를 누르면 x축 방향으로 이동
}
이렇게 Update()
함수 내에서 Input.GetKey
를 사용하면 각 키 입력에 따른 플레이어의 이동을 제어할 수 있다. 키를 누르고 있는 동안 해당 방향으로의 힘이 지속적으로 가해진다.
Unity에서 키보드 입력을 처리하는 방법 중 하나는 Input.GetKey
함수를 사용하는 것이다. 이 함수는 특정 키가 눌러져 있는 동안 true
를 반환한다.
if(Input.GetKey(KeyCode.W))
{
// W 키가 눌러져 있는 동안 실행되는 코드
}
하지만 Input.GetKey
의 사용에는 몇 가지 단점이 있다:
이러한 단점으로 인해 복잡한 입력 로직을 처리하거나 다양한 플랫폼을 지원해야 할 때는 다른 입력 처리 방법을 고려해야 할 수도 있다.
Input.GetAxis
는 Unity에서 연속적인 입력 값을 처리하는 데 사용되는 함수다. 이 함수는 설정된 축의 값을 -1에서 1 사이의 부동 소수점 값으로 반환한다.
float inputX = Input.GetAxis("Horizontal");
float inputZ = Input.GetAxis("Vertical");
Input.GetAxis
의 장점:
void Update()
{
float inputX = Input.GetAxis("Horizontal");
float inputZ = Input.GetAxis("Vertical");
playerRigidbody.AddForce(inputX * speed, 0, inputZ * speed);
}
Input.GetAxis
를 사용하면 키보드 뿐만 아니라 조이스틱과 같은 입력 장치도 쉽게 처리할 수 있다. 이로 인해 플레이어의 조작이 더 자연스럽고 복잡한 입력 로직도 구현할 수 있다.
Unity에서 플레이어의 움직임에 관성을 없애고 싶을 때, Rigidbody의 velocity
변수 값을 직접 변경할 수 있다.
Vector3 velocity = new Vector3(inputX, 0, inputZ);
velocity = velocity * speed;
playerRigidbody.velocity = velocity;
문제점: 이 방법은 떨어지는 속도가 이상해지는 등의 문제를 초래할 수 있다. 플레이어가 바닥을 벗어나면, 중력을 받지 않거나 아주 천천히 떨어지는 이상한 모습이 나타날 수 있다.
해결 방법: 원래 y축의 속도를 보존하여 문제를 해결할 수 있다.
float fallSpeed = playerRigidbody.velocity.y; // 원래 y의 속도를 보존
Vector3 velocity = new Vector3(inputX, 0, inputZ);
velocity = velocity * speed;
velocity.y = fallSpeed; // 원래 y로 설정
playerRigidbody.velocity = velocity; // 최종 속도 설정
이렇게 하면 관성을 없애면서도 중력에 대한 영향을 그대로 받게 해 문제를 해결할 수 있다.
Unity에서 특정 컴포넌트를 가져오려면 GetComponent()
함수를 사용한다. 이 함수는 해당 컴포넌트가 붙어 있다면 찾아서 반환해준다.
Rigidbody playerRigidbody;
void Start()
{
playerRigidbody = GetComponent<Rigidbody>(); // Rigidbody 컴포넌트 찾아서 반환
}
이 함수를 사용하면 스크립트에서 직접 컴포넌트를 참조할 수 있다.
이번 장에서는 플레이어의 조작과 관련된 여러 기능과 컴포넌트를 배웠다. 다양한 입력 방식과 물리적 효과를 활용하여 플레이어의 움직임을 구현하였다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
// 플레이어의 이동 속도
public float speed = 10f;
// 플레이어의 리지드바디 컴포넌트
Rigidbody playerRigidbody;
// 게임이 시작될 때 한 번만 호출되는 함수 -> 초기화
void Start()
{
// GetComponent<타입>() : 타입에 해당하는 컴포넌트를 찾아서 반환
playerRigidbody = GetComponent<Rigidbody>();
}
// 매 프레임마다 호출되는 함수 -> 유저 입력을 받아서 처리
void Update()
{
// GetAxis() : 키보드 입력을 받아서 -1 ~ 1 사이의 값을 반환
float inpuitX = Input.GetAxis("Horizontal"); // 조이스틱 대응 가능
float inputZ = Input.GetAxis("Vertical");
float fallSpeed = playerRigidbody.velocity.y; // 중력에 의해 떨어지는 속도를 유지시키기 위해
// 방향 * 속도 = 속도 벡터
Vector3 velocity = new Vector3(inpuitX, 0f, inputZ);
velocity = velocity * speed; // 방향 * 속도
velocity.y = fallSpeed; // 중력에 의해 떨어지는 속도를 유지시키기 위해
// 리지드바디의 속도를 velocity로 변경
playerRigidbody.velocity = velocity;
}
}