5. Input and Output

혀니앤·2022년 10월 19일
0

지금까지

  • 게임 월드를 업데이트하고, 시각, 청각, 진동 등으로 렌더링했다
  • 사용자의 입력에 따른 업데이트가 핵심이다
  • 사용자의 입력을 어떻게 처리할지가 중요하다

게임 엔진에서의 상호작용

  • 사용자가 입력을 넣는다 (아이템을 집거나 수정하는 등의 입력)
  • 입력을 기반으로 캐릭터의 상태, 주변 환경 의 상태를 보고 가능하면 변형을 주게 된다
  • 변형의 규칙에 의해 변화되고, 게임 로직에 맞게 결과로서 플레이어에게 피드백을 준다

Input Device 의 역할

  • 게임 플레이어가 무엇을 하고 싶은지를 게임 엔진에 전달하는 역할을 한다
  • 실제 이동하려는 동작과 넣는 입력 동작이 관련성 있는 것이 좋다

Input 과 Output 의 요구사항

  • 입력하기 쉬워야 한다
    • 너무 많은 장치가 필요하면 안된다
    • 많은 플레이어가 참여 가능한 디바이스를 사용해야 한다 = 다양한 디바이스를 지원해야 한다
  • 조작하기 쉬워야 한다
    • 마법 동작을 하는 듯한 동작들이 재미는 있지만 인식이 안좋으면 안된다
  • 장르와 특성에 따라 더 많은 요구사항이 생길 수 있다

💡 Input Device

  • 요구사항
    • 입력 장치는 플레이어의 요구를 전달할 수 있어야 한다

    • 조이스틱, 키보드, 마우스 등의 다양한 디바이스를 모두 지원해줘야 한다

    • 서로 다른 하드웨어에 대해 비슷한 컨트롤 방법이나 게임 경험을 제공해야 한다

    • 다양한 연령대와 경험을 가진 사람들을 지원해야 한다

      → 어떻게 하면 지원할 수 있을까?

  • 구분
    • 하드웨어 : 하드웨어 디바이스 자체. 실제 마우스나키보드. 어떤 값이 입력되었는지 인식한다
    • Abstract Device : 조작 장치가 다르더라도 오른쪽으로 이동하는 조작에 기반하여 구분해야 한다
      • 드라이버 : 하드웨어 →Abstract mapping
      • 게임엔진 : Abstract → Logical mapping
    • Logical Device : 실제 발생하는 행동, 동작 결과를 기반으로 구분한다 (Nevigation … )

1. Hardware Device

  • synchronous device
    • 입력이 올 때까지 기다린다
    • 로그인 폼
    • 장점 : 입력이 확실하고 입력값을 확실하게 확인할 수 있다
  • Asynchronous device
    • 현재 값을 가져온다. 이전 값을 잃어버릴 수 있다
    • 사용자가 가장 최근에 준 입력을 받아올 수 있다
    • 장점 : 사용자가 준 입력에 바로바로 반응할 수 있다

2. Abstract Device

  • Generic device : 키보드
  • Position device : Mouse , joystick
  • Feedbace device : 진동 등으로 다시 피드백을 돌려주는 장치
  • 예시 ) DirectInput 에서 추상 기기 만드는 방법
    • DirectInput object 를 만든다
    • 하드웨어를 만들어서 mapping한다
    • 하드웨어와 추상기기 사이의 interface 함수를 만든다

어떤 디바이스를 쓰는 것이 좋을까?

  • 하드웨어 디바이스는 100퍼센트의 장치를 모두 사용할 수 있고 어떤 값을 입력하는지 다 매핑할 수 있다
  • 추상 디바이스는 하드웨어만큼 효율적이지는 않다
  • 논리 디바이스는 추상적이고 유연하게 만들 수 있다. mapping만 잘해주면 효율적으로 만들 수 있지만, mapping 이 2번 일어나므로 비효율적일 수 있다.

→ 게임의 특성을 고려해서 선택하기

Generic Device Processing

  • 하드웨어 디바이스를 추상 디바이스로 mapping하는 디바이스 드라이버를 만든다
  • 추상 디바이스의 값을 논리 디바이스의 값으로 전환해준다
    • 조이스틱의 움직임 값>0.5 면 오른쪽으로 이동하자!
  • 하드웨어 디바이스가 바뀌어도 추상 디바이스로의 mapping만 추가해주면 된다

실제 예제를 보면서 확인해보자

1. Keyboard

  • string input, stroke, command 입력을 사용할 수 있다
  • 장점 : 보편적이고 많은 입력값을 받을 수 있다
  • 단점 : 어떤 키에 어떤 값이 해당하는지 다 알아야 한다
  • 처리 방법
    • 특정 키가 눌리는 전기적인 반응을 확인할 수 있다 (ex- GetAsyncKeyState(keycode); 를 통해 키가 눌렸는지 알 수 있다)

    • 모든 키 상태를 받아와서 한 번에 확인한다 (ex- GetKeyboardState(PBYTE* lpKeyState))

      ⇒ 둘다 ‘현재’의 키 값을 받아오므로 Async

  • 딜레이 문제점
    • 현재 키 값을 읽어오는 순간과 사용자가 누른 순간이 같아야 확인할 수 있다

    • 연속적으로 키를 누르면 놓칠 수 있다

      Loss Issue : 중요한 인풋을 처리할 수 없어지고, 계산 가능한 시간이 짧아짐 (빨리해야 중요한 인풋 받을수있어서 촉박해짐)

  • 해결법
    • Polling : 키 값을 계속 읽어오지만 딜레이가 발생한다
    • Message queue : 키 입력 받을 때마다 병렬로 queue 에 넣고 앞에서부터 하나씩 읽어온다
      • 메세지 큐가 넘치지 않는 한 인풋 값을 모두 처리할 수 있다

2. Mouse

  • 위치 값을 알 수 있는 디바이스
  • 마우스는 기본적으로 Async이지만, 인풋값이 델타 값으로 들어오면서 OS에서 이전 값에 델타를 더하면서 계산하므로 queue가 필요해진다. → 버튼이 눌리는 경우엔 x,y 좌표값을 가지는 queue 가 필요하다
  • 날아가면 안되고 바로바로 읽어와야 하는 값은 마우스에 넣고, 아니면 키보드에 넣자

3. JoyStick

  • 위치 값을 알 수 있지만, 마우스는 델타 값을 받아오지만 조이스틱은 8방향 값만을 가진다
  • 기본적으로는 모든 입력이 구분되므로 Sync로도 사용할 수 있다

💡Mapping

Logical Device

  • 어떤 동작이 필요할까?
    • 고르고, 움직이기
    • Navigation → 가고자하는 목적지, 현재의 위치 값이 필요하다
    • Action → 무슨액션을 할건지, 어떤 값으로 행동이 시작되는지 트리거
    • Mode Change → 트리거가 필요함
  • 어떤 디바이스를 사용해야 할까?
    • 동작에 맞게 디바이스를 선택하면 된다!

Abstract→Logical Mapping

  • 그렇게 쉽기만 하지는 않다..
  • -값이면 외노ㅉㄱ → 실제로 정확한 0 값이 나오기 어렵다. 정지하기 어렵다 → DeadZone 을 두어 값이 작은 일정 구간을 아예 무시한다
  • 이런식으로 함수를 정하고 인식을 위해 보정해야 한다

FeedBack Device

  • 피드백 종류 : 전기자극, 진동, 햅틱, 촉감
  • 피드백 생성
    • 전기자극, 진동 : 물리적 현상에 의해 충격량에 맞춰서 일정한 값을 반환하도록 한다
    • 햅틱 : 물체에 따라 그 반응이 달라지므로 물리적 시뮬레이션을 계산한다
    • 촉감 : 힘을 얼마나 줬는지에 따른 물리적 시뮬레이션을 계산해야 하지만 너무 복잡해서 그냥 미리 만든 일정한 값을 반환한다

결론

  • Input 장치
    • Physical : Synchoronous vs Async
    • Abstract
    • Logical
profile
일단 시작하기

0개의 댓글