입력 Input

데스크톱 Desktop

유니티는 키보드, 조이스틱과 게임패드 입력을 지원함.

:!: 키보드, 조이스틱, 게임패드 입력은 유니티의 데스크탑 버전에서만 작동.

가상 축과 버튼은 입력 매니져 Input Manager (Edit→Project Settings→Input)에서 만들수 있고 사용자는 키보드 입력을 화면 설정 대화창 screen configuration dialogue 에서 설정할 수 있다.

사용자는 조이스틱, 게임패드, 키보드 그리고 마우스를 설정하고 그것들 모두를 하나의 간단한 스크립팅 인터페이스를 통해 접근할 수 있다.

스크립트에서 모든 가상 축은 그들의 이름을 통해 접근하게 된다.

모든 프로젝트는 생성되었을 때 아래의 기본 입력 축 input axe 을 가진다:

  • 수평 Horizontal and 수직 Vertical은 w, a, s, d와 화살표 키로 연결 map 되어 있다.
  • 발사 Fire1, 발사 Fire2, 발사 Fire3 는 각각 Ctrl, Option (Alt), Command으로 연결되어 있다.
  • 마우스 Mouse X마우스 Mouse Y 는 마우스 이동의 델타 delta 와 연결되어 있다.
  • 윈도우 셰이크 Window Shake X윈도우 셰이크 Window Shake Y 는 윈도우 이동과 연결되어 있다.

새로운 입력 축 추가하기 Adding new Input Axes

새로운 입력 축을 추가하고 싶으면 Edit→Project Settings→Input 메뉴로 간다. 여기서 각 축의 설정도 바꿀수 있다.

사용자는 각각의 축을 조이스틱, 마우스, 또는 키보드 키들의 두개의 버튼들에 연결.

Name 스크립트에서 이 축을 확인하기 위한 문자열 string 의 이름.
Descriptive Name 스탠드얼론 빌드에서 설정 대화창의 입력 탭에 보여지는 양의 (+) positive 값을 지닌 이름.
Descriptive Negative Name 스탠드얼론 빌드에서 설정 대화창의 입력 탭에 보여지는 음의 (-) negative 값을 지닌 이름.
Negative Button 음(-)의 방향으로 축을 미는데 사용되는 버튼.
Positive Button 양(+)의 방향으로 축을 미는데 사용되는 버튼.
Alt Negative Button 음(-)의 방향으로 축을 미는데 사용되는 또 다른 버튼.
Alt Positive Button 양(+)의 방향으로 축을 미는데 사용되는 또 다른 버튼.
Gravity 아무 버튼도 누르지 않았을 때 축이 중립 neutral 으로 떨어지는 초당 단위 units per second 속도.
Dead 아날로그 데드존 dead zone 의 크기. 이 범위에 속하는 모든 아날로그 장치 값은 맵이 중립이 되게 만듭니다.
Sensitivity 축이 목표 값으로 가는 초당 단위 속도. 이것은 디지털 장치들에만 해당 된다.
Snap 활성화되면 반대 방향의 버튼을 눌렀을 때 이 축의 값이 0으로 리셋된다.
Invert 활성화되면 음 Negative 버튼들이 양 positive 값을 보내고 그 반대의 경우도 성립.
Type 이 축을 제어할 입력 종류.
Axis 이 축을 제어할 연결 장치의 축.
Joy Num 이 축을 제어할 연결된 조이스틱.

입력의 더 나은 모양과 느낌을 위해서 위의 설정을 이용하라. 이들은 모두 에디터에 풍선도움말 tooltips 로도 볼 수 있다.

스크립트에서 입력 축 이용하기 Using Input Axes from Scripts

사용자는 이런 스크립트를 통해 현재 상태를 아래와 같이 물을 query 수 있다:

value = Input.GetAxis ("Horizontal"); 

축은 -1부터 1까지의 값을 가진다. 중립 위치는 0이다. 이것은 조이스틱과 키보드 입력의 경우이다.

그러나 마우스 델타 Mouse Delta 와 윈도우 셰이크 델타 Window Shake Delta 는 마지막 프레임동안 얼마나 마우스나 윈도우가 움직였는가 이다. 즉 이것은 사용자가 마우스를 빨리 움직이면 그것이 1보다 크거나 -1보다 작을 수도 있다는 말이다.

같은 이름으로 여러 개의 축을 만드는 것은 가능. 입력 축 input axis 을 얻을 때는 가장 큰 절대값을 가진 축이 불려온다. 이것은 하나의 축 이름에 하나 이상의 입력 장치를 할당하는 것을 가능하게 . 예를 들어, 키보드 입력을 위한 축 하나를 만들고 같은 이름으로 조이스틱 입력을 위한 축을 만듭니다. 만약 사용자가 조이스틱을 이용하면 입력은 조이스틱에서 올 것이고 그렇지 않으면 입력은 키보드에서 오게 될 것이다. 이 방식을 통하여 사용자는 스크립트를 작성할 때 입력이 어디서 올 지 신경쓸 필요가 없게 된다.

버튼 이름 Button Names

하나의 키를 어떤 축과 연결시키기 위해서는 키의 이름을 인스펙터 InspectorPositive Button 또는 Negative Button 속성에 넣어야 .

키의 이름은 아래의 관례를 따릅니다:

  • 보통 키: "a", "b", "c" …
  • 숫자 키: "1", "2", "3", …
  • 방향 키: "up", "down", "left", "right"
  • 키패드 키: "[1]", "[2]", "[3]", "[+]", "[equals]"
  • 수정 키: "right shift", "left shift", "right ctrl", "left ctrl", "right alt", "left alt", "right cmd", "left cmd"
  • 마우스 버튼: "mouse 0", "mouse 1", "mouse 2", …
  • 조이스틱 버튼 (모든 조이스틱에서): "joystick button 0", "joystick button 1", "joystick button 2", …
  • 조이스틱 버튼(특정 조이스틱에서): "joystick button 0", "joystick button 1", "joystick 1 button 0", …
  • 특수 키: "backspace", "tab", "return", "escape", "space", "delete", "enter", "insert", "home", "end", "page up", "page down"
  • 기능 키: "f1", "f2", "f3", …

키들을 식별하기 위한 이름은 스크립팅 인터페이스에서나 인스펙터에서나 같다.

value = Input.GetKey ("a"); 

모바일 입력 Mobile Input

유니티 iOS/안드로이드는 InputiOS Input 스크립트 인터페이스를 통해 아이폰, 아이패드, 그리고 안드로이드 입력 시스템에 접근할 수 있게 해준다.

Input은 멀티터치 스크린, 가속도계 accelerator 그리고 기기의 화면방향 device orientation 에 접근하게 해준다. iOS Input 는 지리적 위치 정보에 접근하게 해준다.

모바일 장치에서 키보드로의 접근은 iOS keyboard를 통해 제공된다.

멀티터치 스크린 Multi-Touch Screen

아이폰과 아이팟 터치 장치는 다섯 손가락의 동시 터치를 감지할 수 있다. 사용자는 Input.touches 속성 배열 property array 을 통해 마지막 프레임 동안 화면을 만진 각 손가락에 대한 상태를 가져올 수 있다.

안드로이드 장치들은 한번에 얼마나 많은 손가락 터치를 감지할 지에 대한 일관된 제한 기준이 없다. 조금 오래된 장치에서는 두 손가락 터치, 조금 더 최신 장치에서는 다섯 손가락까지 이것은 장치마다 다 틀립니다.

각 손가락 터치는 Input.Touch의 데이타 구조로 표현된다:

fingerId
position
deltaPosition
deltaTime
tapCount
phase

터치상태인 페이즈 Phase 는 아래 중 하나의 상태에 있게 된다:

Began
Moved
Stationary
Ended
Canceled

다음은 유저가 화면을 탭 할때마다 광선 ray 을 뿌리는 예제 스크립트이다:

var particle : GameObject;
function Update () {
    for (var touch : Touch in Input.touches) {
        if (touch.phase == TouchPhase.Began) {
            //현재 터치 좌표에서 광선을 만듭니다.
            var ray = Camera.main.ScreenPointToRay (touch.position);
            if (Physics.Raycast (ray)) {
                //히트시 파티클을 생성.
                Instantiate (particle, transform.position, transform.rotation);
            }
        }
    }
}

마우스 시뮬레이션 Mouse Simulation

본래의 터치 지원 이외에도 유니티 iOS/안드로이드는 마우스 시뮬레이션을 제공. 사용자는 표준 Input 클래스에서 마우스 기능을 사용할 수 있다.

장치 방향 Device Orientation

유니티 iOS/안드로이드는 사용자가 3차원 공간에서 기기의 실제 물리적 방향의 분리된 정보를 얻는 것을 가능하게 . 사용자가 어떻게 장치를 들고 있는가에 따라 게임의 행동 behaviors 이 반응하게 만들고 싶다면 방향 변화의 감지는 유용히 쓰일 수 있다.

사용자는 Input.deviceOrientation 속성에서 장치 방향에 대한 정보를 얻을 수 있다. 방향은 아래 중에 하나의 값을 가진다:

Unknown
Portrait
PortraitUpsideDown
LandscapeLeft
LandscapeRight
FaceUp
FaceDown

가속도계 Accelerometer

모바일 장치가 움직이면서 내장된 가속도계 accelerometer 는 3D 공간에서 일차적인 세 개의 축에 대한 선형 가속 변화 llinear acceleration changes 를 보고. 각 축 방향으로의 가속은 G-force 값으로 하드웨어에 의해 직접 보고 되어진다. 값 1.0은 주어진 축에서 +1g의 양을 나타내며 -1.0은 -1g를 나타냅니다. 만약 사용자가 장치를 정면으로 보고 똑바로 세워서 잡고 있으면 (홈버튼이 바닥에 위치) X축은 오른쪽으로 양수값이며 Y축은 위쪽으로 양수이며 Z축은 사용자 쪽으로 양수값을 가진다.

가속도계 값은 Input.acceleration 속성에서 얻을 수 있다.

아래는 가속도계를 이용해서 객체를 움직이는 예제 스크립트이다:

var speed = 10.0;
function Update () {
    var dir : Vector3 = Vector3.zero;
 
    // 장치가 지면과 평행하게 놓여있다고 가정
    // 홈 버튼이 오른손 쪽에 위치해 있다
 
    // 장치 가속도 축을 게임 좌표에 재적용:
    //  1) 장치의 XY 평면이 XZ평면에 적용된다
    //  2) Y축을 따라 90도 회전 되었다.
    dir.x = -Input.acceleration.y;
    dir.z = Input.acceleration.x;
 
    // 가속 벡터를 단위 구 unit sphere 에 고정.
    if (dir.sqrMagnitude > 1)
        dir.Normalize();
 
    //이것을 프레임당 10미터 대신 초당 10미터로 이동하게 만듭니다.
    dir *= Time.deltaTime;
 
    //객체를 이동.
    transform.Translate (dir * speed);
}

로우-패스 필터 Low-Pass Filter

가속도계를 읽는 것은 불규칙한 곳들과 노이즈가 많다. 로우-패스 필터 Low-pass filter 를 신호 signal 에 적용시키는 것은 사용자가 그것을 완화시키고 고주파 노이즈를 제거하게 해준다.

아래의 스크립트는 사용자가 어떻게 로우-패스 필터를 가속도계 읽기에 적용시키는지 보여준다:

var AccelerometerUpdateInterval : float = 1.0 / 60.0;
var LowPassKernelWidthInSeconds : float = 1.0;
 
private var LowPassFilterFactor : float = AccelerometerUpdateInterval / LowPassKernelWidthInSeconds; // tweakable
private var lowPassValue : Vector3 = Vector3.zero;
function Start () {
    lowPassValue = Input.acceleration;
}
 
function LowPassFilterAccelerometer() : Vector3 {
    lowPassValue = Mathf.Lerp(lowPassValue, Input.acceleration, LowPassFilterFactor);
    return lowPassValue;
}

LowPassKernelWidthInSeconds 의 값이 클수록 필터된 값이 현재 입력 샘플 input sample 에 모이는 것이 느려지게 될 것이다 (반대의 경우도 마찬가지). 사용자는 avgSamples() 대신 LowPassFilter() 함수를 사용할 수 있다.

가속도계를 읽을 때 가장 정밀한 값을 원한다면 어떻게 해야 하나요?

Input.acceleration 변수를 읽는 것은 하드웨어를 샘플링하는 것과 같은 것이 아니다. 간단히 말하면 유니티는 하드웨어를 60Hz의 빈도로 샘플을 모으며 그 결과를 해당 변수에 저장. 현실적으로는 이것은 조금 더 복잡. 만약 CPU에 부담이 굉장히 많은 상황이 되면 가속도계의 샘플링은 일정한 시간 간격으로 일어나지 않는다. 그 결과 시스템은 한 프레임에선 2개의 샘플을 보고하기도 하고 다음 프레임에선 1개의 샘플을 보고하기도 .

프레임에서 가속도계가 그 프레임에서 실행한 모든 측정 정보에 접근할 수 있다. 아래의 코드는 마지막 프레임안에서 수집된 모든 가속도계 이벤트의 간단한 평균을 보여줄 것이다:

var period : float = 0.0;
var acc : Vector3 = Vector3.zero;
for (var evnt : iPhoneAccelerationEvent  in iPhoneInput.accelerationEvents) {
    acc += evnt.acceleration * evnt.deltaTime;
    period += evnt.deltaTime;
}
if (period > 0)
    acc *= 1.0/period;
return acc;

추가 읽기 Further Reading

유니티 모바일 입력 API는 원래 애플의 API에 기반을 둡니다. 유니티의 입력 API를 더 잘 이해하기 위해서는 원래 API를 배우면 도움이 될 것이다. 아래에서 애플 입력 API문서를 찾을 수 있다: *Programming Guide: Event Handling (애플 아이폰 SDK 문서) *UITouch Class Reference (애플 iOS SDK 문서)

_주의:_ 위 링크들은 사용자의 로컬 설치된 아이폰 SDK 참조 문서 iPhone SDK Reference Documentation 를 참조하고 본래 ObjectiveC 코드를 포함하고 있을 것이다. 유니티를 모바일 장치에서 사용하기 위해 꼭 위의 문서들을 이해할 필요는 없으나 도움이 되는 분들이 있을 것이다!

iOS!

장치의 지리적 위치 Device geographical location

장치의 지리적 위치는 iPhoneInput.lastLocation 속성을 통해 얻을 수 있다. 사용자는 이 속성을 호출하기 전에 iPhoneSettings.StartLocationServiceUpdates()를 이용해서 위치 서비스 업데이트를 시작하고 iPhoneSettings.locationServiceStatus를 통해 서비스 상태를 확인해야 할 것이다. 자세한 사항은 scripting reference를 보라.

역링크