사용자는 기기, 터치 또는 제스처 입력을 사용하여 앱을 제어할 수 있습니다. 그리고, 그래픽 사용자 인터페이스(GUI), 키보드 및 마우스, 조이스틱, 컨트롤러, 터치 스크린, 모바일 기기의 움직임 감지 기능(예:가속센서 또는 자이로스코프), VR 및 AR 컨트롤러 등을 사용해 사용자는 게임을 컨트롤 할 수 있게 됩니다.
입력 관리자
유니티의 메인 메뉴 Edit > Project Settings로 이동 후 오른쪽 내비게이션에서 input Manager를 선택합니다.
- 키(key) : W,A,S,D, Shift, space 등 키보드의 물리적인 키를 Key라 유니티에서 칭합니다.
- 버튼(Button) : 리모콘, 게임기의 X버튼 처럼 게임패드에 있는 버튼을 유니티에서 Button이라 칭합니다.
- 축 : 버튼, 키 등과 같은 컨트롤에 맵핑이 됩니다. 사용자가 컨트롤을 활성화 하면 [-1.1] 범위의 값을 수신합니다. 이 값은 스크립트에서도 사용할 수 있습니다.
유니티 측 문서의 예제
Horizontal 및 Vertical 축의 입력 후 transform.Translate 메서드를 사용해 XZ공간(전방, 후방, 왼쪽, 오른쪽)에서 오브젝트를 움직일 수 있도록 만듭니다. update()메서드에서 다음 코드를 추가하면 오브젝트가 움직이게 됩니다.
float moveSpeed = 10;
//Define the speed at which the object moves.
float horizontalInput = Input.GetAxis("Horizontal");
//Get the value of the Horizontal input axis.
float verticalInput = Input.GetAxis("Vertical");
//Get the value of the Vertical input axis.
transform.Translate(new Vector3(horizontalInput, verticalInput, 0) * moveSpeed * Time.deltaTime);
//Move the object to XYZ coordinates defined as horizontalInput, 0, and verticalInput respectively.
Time.deltaTime은 모든 컴퓨터의 성능이 다르므로 모든 컴퓨터의 성능 관련 없이 시간을 같게 만들어, 속도가 빨라지거나 느려지는 것을 방지하기 위한 시간타임입니다. 컴퓨터가 멈춘다고, 시간이 멈추면 안되는 것은 아시죠? 사람들이 일하다가 렉 걸리듯 멈춘다고 시간이 멈추지는 않으니까요.
모바일 디바이스 입력
모바일 디바이스는 input 클래스를 통해 터치스크린, 가속 센서, 지리나 위치정보 입력 등을 액세스 해올 수가 있습니다.
저는 안드로이드 게임 개발을 생각하고 있으니, 안드로이드에 대한 부분으로 설명하겠습니다.
안드로이드 디바이스의 경우에는 터치 인지를 할 수 있는 갯수 제한이 없습니다. 인지 갯수는 디바이스마다 다르고, 구형 디바이스는 2곳 터치, 일부 최신 디바이스에서는 5곳 까지 인식 할 수 있습니다.
< Input.Touch >
속성 | 세부 사항 |
fingerId | 터치에 대한 고유 인덱스 |
position | 터치 화면 위치 |
deltaPosition | 마지막 프레임 이후로 화면 위치가 변경됩니다. |
deltaTime | 마지막 상태 변경 이후 경과된 시간입니다. |
tapCount | iPhone/iPad 화면은 사용자가 빠른 손가락 탭을 구별할 수 있습니다. 이 카운터는 사용자가 손가락을 옆으로 움직이지 않고 화면을 몇 번 두드렸는지 알려줍니다. Android 장치는 탭 수를 계산하지 않습니다. 이 필드는 항상 1입니다. |
phase | 터치 상태를 설명하며, 사용자가 화면을 터치하기 시작했는지, 손가락을 움직였는지, 손가락을 들어올렸는지 확인하는 데 도움이 됩니다. |
phase에서 Began | 화면에 손가락이 닿았어요. |
phase에서 Moved | 화면에서 손가락이 움직였다. |
phase에서 Stationary | 손가락이 화면에 닿지만 마지막 프레임 이후로 움직이지 않습니다. |
phase에서 Ended | 화면에서 손가락 하나가 들려왔다. 이것이 터치의 마지막 단계입니다. |
phase에서 Canceled | 사용자가 (예를 들어) 기기를 얼굴에 대거나 다섯 번 이상의 터치가 동시에 발생했을 때 시스템이 터치 추적을 취소했습니다. 이것이 터치의 마지막 단계입니다. |
< 다음은 화면을 터치 할 때마다 손가락으로 광선을 방사하는 예제 스크립트 입니다. 모바일 터치 쓰는법! .>
이것도 유니티 홈페이지에 메뉴얼에 있는 예제입니다.
using UnityEngine;
public class TouchInput : MonoBehaviour
{
GameObject particle;
void Update()
{
foreach(Touch touch in Input.touches)
{
if (touch.phase == TouchPhase.Began)
{
// Construct a ray from the current touch coordinates
Ray ray = Camera.main.ScreenPointToRay(touch.position);
if (Physics.Raycast(ray))
{
// Create a particle if hit
Instantiate(particle, transform.position, transform.rotation);
}
}
}
}
}
마우스 시뮬레이션
유니티 안드로이드는 마우스 시뮬레이션을 지원합니다. 네이티브 터치 지원도 하지만, 마우스 기능은 스탠다드 Input 클래스를 통해 사용할 수 있습니다. 안드로이 디바이스는 멀티 터치를 지원하게 설계되었다는 점을 유의해야합니다. 마우스 기능을 사용하면 단일 터치만 지원합니다.
모바일 디바이스에서는 터치 입력시에 한 지점을 터치했다가 다른 지점을 터치하더라도 두 지점 사이를 이동한 것으로 처리가 되지 않지만 마우스를 시뮬레이션 할 경우는 두 지점에서 일어난 터치를 이동한 것으로 처리해버리기에 모바일 터치와 마우스 터치를 구분해서 사용해야 합니다.
모바일 디바이스 | 한 지점을 터치했다가 다른 지점을 터치하더라도 두 지점 사이를 이동한 것으로 처리가 되지 않는다. |
마우스 디바이스 | 한 지점을 터치했다가 다른 지점을 터치하더라도 두 지점에서 일어난 터치를 이동한 것으로 처리 |
가속 센서(Accelerometer)
모바일 디바이스가 움직이면 3차원 공간에서 가속 센서가 주축에 대한 선형 가속도 변화를 알려줍니다. 각 축에 대한 가속도는 G-force의 값으로 직접 하드웨어에서 통보가 됩니다. 만약 값이 1.0이면 주어진 축에 약 +1g의 하중이 실린다는 것이고, 값이 -1.0이라면 -1g이 실린다는 의미입니다.
홈 버튼이 아래에 위치하도록 똑바로 폰을 들면 X축은 오른쪽을 따라 양의 값을 나타내고, Y축은 위쪽을 따라 양의 값을 나타냅니다. Z축은 사용자 쪽을 따라 양의 값을 나타냅니다.
가속센서의 값은 Input.acceleration 프로퍼티에 액세스하면 가져올 수 있습니다.
< 다음은 가속 센서를 통해 오브젝트를 움직이는 예제입니다.>
유니티 문서 예제
using UnityEngine;
public class Accelerometer : MonoBehaviour
{
float speed = 10.0f;
void Update()
{
Vector3 dir = Vector3.zero;
// we assume that the device is held parallel to the ground
// and the Home button is in the right hand
// remap the device acceleration axis to game coordinates:
// 1) XY plane of the device is mapped onto XZ plane
// 2) rotated 90 degrees around Y axis
dir.x = -Input.acceleration.y;
dir.z = Input.acceleration.x;
// clamp acceleration vector to the unit sphere
if (dir.sqrMagnitude > 1)
dir.Normalize();
// Make it move 10 meters per second instead of 10 meters per frame...
dir *= Time.deltaTime;
// Move object
transform.Translate(dir * speed);
}
}
로우 패스 필터(Low-Pass Filter)
가속 센서 조회값이 요동 칠때나 노이즈가 있을 때가 있는데 이것을 신호에 로우 패스 필터링을 적용시키면 하이 프리퀀시 노이즈를 제거해 좀 더 부드럽게 만들 수 있게 됩니다.
<다음 스크립트는 가속 센서를 읽을 때에 로우 패스 필터링을 적용한 방법입니다.>
유니티 문서 예제입니다.
LowPassKernelWidthInSeconds 의 값이 클수록, 필터링 된 값이 현재 입력 샘플로 수렴하는 속도가 느려집니다. 반대로 값이 작다면 빨라집니다.
using UnityEngine;
public class LowPassFilterExample : MonoBehaviour
{
float accelerometerUpdateInterval = 1.0f / 60.0f;
float lowPassKernelWidthInSeconds = 1.0f;
private float lowPassFilterFactor;
private Vector3 lowPassValue = Vector3.zero;
void Start()
{
lowPassFilterFactor = accelerometerUpdateInterval / lowPassKernelWidthInSeconds;
lowPassValue = Input.acceleration;
}
private void Update()
{
lowPassValue = LowPassFilterAccelerometer(lowPassValue);
}
Vector3 LowPassFilterAccelerometer(Vector3 prevValue)
{
Vector3 newValue = Vector3.Lerp(prevValue, Input.acceleration, lowPassFilterFactor);
return newValue;
}
}
가속 센서를 읽을 때에 최대한 정확한 결과를 얻으려면 어찌해야 할까?
꼭! 알고 있어야 하는 부분이 Input.acceleration 변수를 읽었을 때에 값이 하드웨어랑 동일하게 샘플 되는 것은 아닙니다. 쉽게 말하자면, 유니티는 하드웨어를 60Hz 주기로 샘플링하고 그에 대한 결과를 변수에 저장하는 방식입니다. 실제로는 더 복잡하지만 가속 센서의 샘플링은 CPU 부하가 클 경우 일정한 시간 간격으로 일어나지 않게 되어있습니다. 따라서 시스템에서의 한 프레임 동안 두 개의 샘플을 보낼 수도 있고, 그 다음 프레임 동안에는 다시 한 개의 샘플만 보낼 수도 있게 된다는 겁니다.
해당 프레임 동안 가속 센서가 측정한 모든 측정치를 액세스 할 수 있습니다.
<마지막 프레임에서 수집된 모든 가속도 센서 이벤트의 단순 평균을 나타낸다.>
유니티 문서 예제임.
public class AccelerationEvents : MonoBehaviour
{
void Update()
{
GetAccelerometerValue();
}
Vector3 GetAccelerometerValue()
{
Vector3 acc = Vector3.zero;
float period = 0.0f;
foreach(AccelerationEvent evnt in Input.accelerationEvents)
{
acc += evnt.acceleration * evnt.deltaTime;
period += evnt.deltaTime;
}
if (period > 0)
{
acc *= 1.0f / period;
}
return acc;
}
}
'Unity Study' 카테고리의 다른 글
[Unity] UI 툴킷, 사용자 인터페이스(UI) 개발을 위한 기능, 리소스 및 툴 컬렉션 (0) | 2023.01.22 |
---|---|
01. 유니티 2D 새 프로젝트 만들기 (0) | 2023.01.08 |
유니티 2D 게임 개발 시작 전 중요한 기본적 지식 (0) | 2023.01.07 |
유니티 2D를 전문적으로 연구하고 공부하는 블로그 (0) | 2023.01.06 |
댓글