이번 글에서는 유니티에서 키보드와 마우스의 입력을 어떻게 인식하고 처리하는지에 대해 설명하도록 하겠습니다.
1. 키보드 입력
유니티에서 키보드 입력 처리는 아래의 코드와 같이 처리합니다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CubeHandler : MonoBehaviour
{
public float speed;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetKey(KeyCode.LeftArrow))
{
transform.Translate(Vector3.left * speed * Time.deltaTime);
}
else if (Input.GetKey(KeyCode.RightArrow))
{
transform.Translate(Vector3.right * speed * Time.deltaTime);
}
else if (Input.GetKey(KeyCode.UpArrow))
{
transform.Translate(Vector3.up * speed * Time.deltaTime);
}
else if (Input.GetKey(KeyCode.DownArrow))
{
transform.Translate(Vector3.down * speed * Time.deltaTime);
}
}
}
게임을 플레이하는 사용자가 언제 키보드 입력을 할지 알 수 없기 때문에 매 프레임마다 호출되는 Update() 함수에서 입력이 있는지 확인해야 합니다.
위 코드에 중요한 함수 두 가지가 사용되었습니다.
- Input.GetKey 함수
Input 은 유니티에서 제공해주는 클래스이며 입력과 관련된 여러가지 처리를 도와주는 클래스입니다. 이 함수는 키보드의 특정 키가 눌려 있는지 검사해 줍니다. 입력 파라미터는 열거형인 KeyCode 입니다. 키보드의 키 눌림을 검사하는 함수는 이 외에 Input.GetKeyDown과 Input.GetKeyUp 도 있습니다. 각각 키보드의 키를 누를 때와 뗄 때 true가 반환됩니다.
KeyCode에 정의된 모든 속성은 다음의 공식 문서를 참고하시면 됩니다.
https://docs.unity3d.com/kr/2021.3/ScriptReference/KeyCode.html
- transform.Translate 함수
이 함수는 오브젝트의 현재위치에서 주어진 파라미터의 크기와 방향만큼 오브젝트를 이동시킵니다. 코드에서 파라미터 값으로 사용된 [Vector3.left * speed * Time.deltaTime] 의 의미는 다음과 같습니다.
- Vector3.left: (-1, 0, 0) 을 반환하며 이동해야 할 방향을 의미합니다.
- speed * Time.deltaTime: 속도 * 시간 = 거리 이므로 이동해야 할 거리를 의미합니다.
- Vector3.left * speed * Time.deltaTime = (-1, 0, 0) * speed * Time.deltaTime = (-speed * Time.deltaTime, 0, 0) 입니다.
즉, x축의 음수 방향인 왼쪽으로 speed * Time.deltaTime 의 거리만큼 이동시킵니다.
2. 마우스 입력
이번엔 마우스 입력을 어떻게 처리하는지에 알아보겠습니다. 아래의 코드는 게임 화면상에 마우스를 클릭하면 클릭한 위치로 큐브를 이동시키는 코드입니다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CubeHandler : MonoBehaviour
{
public float speed;
Vector3 targetPos;
// Start is called before the first frame update
void Start()
{
targetPos = transform.position;
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0))
{
targetPos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 10f));
}
else if (transform.position != targetPos)
{
transform.position = Vector3.MoveTowards(transform.position, targetPos, speed * Time.deltaTime);
}
}
}
위의 코드를 분석하기 전에 먼저 좌표계에 대해서 간단히 알아보도록 하겠습니다.
- 3D 좌표는 X, Y, Z 3개의 축으로 이루어진 실수형의 월드 좌표계입니다.
- 마우스는 X, Y 2개의 축으로 이루어진 정수형의 스크린 좌표계입니다.
Input.mousePosition 은 현재 게임 화면상에 위치한 마우스 포인터의 좌표 정보입니다. 이 좌표는 스크린 좌표계입니다. 하지만 큐브는 실수형의 3D 좌표계를 사용하기 때문에 스크린 좌표계와는 맞지 않습니다. 이를 위해 유니티는 스크린 좌표계를 월드 좌표계로 변환할 수 있는 방법을 제공합니다.
코드를 보면 Camera.main.ScreenToWroldPoint 함수가 있습니다. (Camera.main 은 현재 씬에서 메인으로 사용되는 카메라 오브젝트를 의미합니다.) 이 함수의 입력 파라미터에서 Input.mousePosition.x 와 Input.mousePosition.y 는 스크린 좌표계이며 10f 는 월드 좌표계입니다.
변환 함수를 수행하면 Input.mousePosition.x 와 Input.mousePosition.y 는 해당 위치의 월드 좌표계로 변환되어 반환되고, 10f 는 Main Camera 오브젝트 위치의 z 값과 더해진 결과가 반환됩니다.
Hierarchy 창에 보면 "Main Camera" 오브젝트가 있습니다. 이 오브젝트를 클릭하면 인스펙터 창이 Main Camera 오브젝트의 컴포넌트들을 보여줍니다. 여기서 보면 카메라 위치의 z 값이 -10 인 것을 알 수 있습니다. 변환 함수가 z 값을 카메라 위치의 z 와 입력 시 넘겨준 z 를 더한 값을 넘겨준다고 했으니 변환된 z 는
-10 (카메라 위치의 z 값) + 10 (파라미터의 z 값) = 0
이 됩니다.
실제로 코드를 작성하고 실행하신 후 게임 화면을 마우스로 클릭하면 큐브가 클릭한 위치로 이동하는 것을 보실 수 있습니다. 이 때 큐브의 z 값은 0 입니다. 큐브의 z 위치를 다르게 하고 싶으시면 변환 함수에 넘기는 파라미터의 z 값을 다르게 주시면 됩니다. 실제로 z 값을 변경하고 확인해 보시기 바랍니다.
'게임 프로그래밍 > 유니티(2021.3 LTS) 강좌' 카테고리의 다른 글
[유니티 기초] 에셋 스토어 (Asset Store) 사용 (0) | 2022.10.24 |
---|---|
[유니티 기초] 충돌 처리 (Rigidbody, Colliders) (0) | 2022.10.21 |
[유니티 기초] 스크립트 직렬화 (Script Serialization) (0) | 2022.10.19 |
[유니티 기초] 오브젝트 회전과 Time.deltaTime (0) | 2022.10.18 |
[유니티 기초] 스크립트의 이해와 코드 작성 (0) | 2022.10.14 |
댓글