๋ฐ˜์‘ํ˜•

๐ŸŽฎ Unity Input System - InputAction ์™„์ „ ์ •๋ณต

1. ๐Ÿงญ InputAction์ด๋ž€?

InputAction์€ Unity์˜ ์ƒˆ Input System์—์„œ ์‚ฌ์šฉ์ž์˜ ์ž…๋ ฅ์„ ์ถ”์ƒํ™”ํ•˜์—ฌ "ํ–‰๋™" ๋‹จ์œ„๋กœ ์ •์˜ํ•˜๋Š” ๊ตฌ์„ฑ ์š”์†Œ์ž…๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด Jump, Move, Shoot ๊ฐ™์€ ๊ฒŒ์ž„ ๋‚ด ํ–‰๋™(ํ–‰์œ„) ์„ ์ •์˜ํ•˜๊ณ , ์—ฌ๊ธฐ์— ์–ด๋–ค ํ‚ค๋ณด๋“œ/๋งˆ์šฐ์Šค/๊ฒŒ์ž„ํŒจ๋“œ ์ž…๋ ฅ์ด ์—ฐ๊ฒฐ๋ ์ง€๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.


๐Ÿ“ฆ InputAction ๊ตฌ์„ฑ ๊ตฌ์กฐ

InputActionAsset
 โ””โ”€ Action Map (์˜ˆ: Player)
     โ””โ”€ InputAction (์˜ˆ: Move, Jump)
         โ””โ”€ Binding (์˜ˆ: WASD, Spacebar, Gamepad A๋ฒ„ํŠผ)
  • InputActionAsset: ๋ชจ๋“  ์ž…๋ ฅ ํ–‰๋™์„ ๋‹ด๋Š” ์„ค์ • ํŒŒ์ผ (๋ณดํ†ต .inputactions ํ™•์žฅ์ž)
  • Action Map: ๋…ผ๋ฆฌ์ ์ธ ์ž…๋ ฅ ๊ทธ๋ฃน (์˜ˆ: Player, UI, Vehicle ๋“ฑ)
  • InputAction: ์‹ค์ œ ํ–‰๋™ ์ •์˜ (Move, Jump, Fire ๋“ฑ)
  • Binding: ํŠน์ • ์ž…๋ ฅ ์žฅ์น˜์™€์˜ ์—ฐ๊ฒฐ (ํ‚ค๋ณด๋“œ, ๋งˆ์šฐ์Šค, ๊ฒŒ์ž„ํŒจ๋“œ ๋“ฑ)

โš™๏ธ ๊ธฐ์กด ๋ฐฉ์‹ vs InputAction

๊ธฐ์กด ๋ฐฉ์‹ InputAction
Input.GetKeyDown(KeyCode.Space) InputAction("Jump").performed += ...
์ฝ”๋“œ ๋‚ด์— ์ง์ ‘ ํ‚ค ์ž…๋ ฅ ์ฒดํฌ ํ–‰๋™ ๋‹จ์œ„๋กœ ์ถ”์ƒํ™”๋œ ๊ตฌ์กฐ
์ž…๋ ฅ๋งˆ๋‹ค ์กฐ๊ฑด๋ฌธ ํ•„์š” ์ž…๋ ฅ ํ–‰๋™๋ณ„๋กœ ๋ถ„๋ฆฌ ๊ฐ€๋Šฅ
๋””๋ฐ”์ด์Šค ๋ณ€๊ฒฝ ์‹œ ์ฝ”๋“œ ์ˆ˜์ • ํ•˜๋‚˜์˜ Action์— ์—ฌ๋Ÿฌ ๋””๋ฐ”์ด์Šค ๋ฐ”์ธ๋”ฉ ๊ฐ€๋Šฅ

๐Ÿ’ฌ ํ•œ ๋งˆ๋””๋กœ ์ •๋ฆฌํ•˜๋ฉด?

"InputAction์€ '์–ด๋–ค ํ‚ค๋ฅผ ๋ˆŒ๋ €๋Š”๊ฐ€'๊ฐ€ ์•„๋‹ˆ๋ผ, '์–ด๋–ค ํ–‰๋™์„ ์‹คํ–‰ํ•  ๊ฒƒ์ธ๊ฐ€'์— ์ง‘์ค‘ํ•˜๋Š” ์‹œ์Šคํ…œ์ž…๋‹ˆ๋‹ค."

์ด ๋ฐฉ์‹์€ ๋ณต์žกํ•œ ์ž…๋ ฅ ์ฒ˜๋ฆฌ, ๋‹ค์–‘ํ•œ ๋””๋ฐ”์ด์Šค ๋Œ€์‘, ๊น”๋”ํ•œ ์ฝ”๋“œ ๊ตฌ์กฐ ๋“ฑ์„ ๋ชจ๋‘ ๋งŒ์กฑ์‹œํ‚ฌ ์ˆ˜ ์žˆ์–ด ์ค‘๋Œ€ํ˜• ํ”„๋กœ์ ํŠธ์—์„œ ํŠนํžˆ ๊ฐ•๋ ฅํ•œ ์ž…๋ ฅ ์ฒ˜๋ฆฌ ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค.


2. ๐ŸŽฏ InputAction ํƒ€์ž… ์ข…๋ฅ˜

InputAction์„ ๋งŒ๋“ค ๋•Œ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋Š” Action Type์€ ์„ธ ๊ฐ€์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค:

โ‘  Button (๋ฒ„ํŠผ ์ž…๋ ฅ)

  • ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ์ž…๋ ฅ ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.
  • ํ‚ค๋ณด๋“œ๋‚˜ ๊ฒŒ์ž„ํŒจ๋“œ์˜ ํŠน์ • ๋ฒ„ํŠผ์ฒ˜๋Ÿผ ๋ˆŒ๋ €๋‹ค ๋—๋‹ค์˜ ์ด๋ฒคํŠธ๋ฅผ ๊ฐ์ง€ํ•ฉ๋‹ˆ๋‹ค.
  • ์˜ˆ: ์ ํ”„, ๊ณต๊ฒฉ, ์ƒํ˜ธ์ž‘์šฉ ๋“ฑ
InputAction jumpAction = new InputAction(type: InputActionType.Button);
jumpAction.performed += ctx => Jump();
  • ๊ด€๋ จ phase:
    • started: ๋ฒ„ํŠผ์ด ๋ˆŒ๋ฆฌ๋Š” ์ˆœ๊ฐ„
    • performed: ๋™์ž‘์ด ์ˆ˜ํ–‰๋œ ์ˆœ๊ฐ„
    • canceled: ๋ฒ„ํŠผ์—์„œ ์†์„ ๋—€ ์ˆœ๊ฐ„

โ‘ก Value (๊ฐ’ ์ž…๋ ฅ)

  • ๋ฐฉํ–ฅํ‚ค, ์Šคํ‹ฑ, ๋งˆ์šฐ์Šค ์ด๋™ ๋“ฑ ์—ฐ์†์ ์ธ ๊ฐ’์„ ์ฒ˜๋ฆฌํ•  ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • Vector2, float, int ๋“ฑ ๋‹ค์–‘ํ•œ ํƒ€์ž…์˜ ๊ฐ’์„ ๋ฐ›์•„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์˜ˆ: ์ด๋™, ๋งˆ์šฐ์Šค ์œ„์น˜, ์คŒ ๋ ˆ๋ฒจ ๋“ฑ
InputAction moveAction = new InputAction(type: InputActionType.Value);
Vector2 moveDir = moveAction.ReadValue<Vector2>();

โ‘ข Pass-through (์ฆ‰์‹œ ์ „๋‹ฌํ˜•)

  • Unity ์ด๋ฒคํŠธ๋‚˜ ๋‹ค๋ฅธ ์ฒ˜๋ฆฌ ๋กœ์ง์„ ํ†ตํ•˜์ง€ ์•Š๊ณ  ๋ฐ”๋กœ ๊ฐ’ ์ „๋‹ฌ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • performed๋งŒ ํ˜ธ์ถœ๋˜๋ฉฐ started, canceled์€ ํ˜ธ์ถœ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ๋ณดํ†ต ์ฒ˜๋ฆฌ ๊ณผ์ •์„ ์ƒ๋žตํ•˜๊ณ  ์ž…๋ ฅ ๊ฐ’์„ ๊ทธ๋Œ€๋กœ ๋„˜๊ฒจ์•ผ ํ•  ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
InputAction lookAction = new InputAction(type: InputActionType.PassThrough);
lookAction.performed += ctx => Look(ctx.ReadValue<Vector2>());

โœ… ํƒ€์ž… ์„ ํƒ ๊ธฐ์ค€ ์š”์•ฝ

ํƒ€์ž… ์‚ฌ์šฉ ์˜ˆ์‹œ ํŠน์ง•
Button ์ ํ”„, ๊ณต๊ฒฉ ์ƒํƒœ ๋ณ€ํ™”๊ฐ€ ์žˆ๋Š” ๋‹จ์ˆœ ์ž…๋ ฅ ์ฒ˜๋ฆฌ
Value ์ด๋™, ์นด๋ฉ”๋ผ, ์คŒ ๊ฐ’์˜ ๋ณ€ํ™”๋Ÿ‰์„ ์ง€์†์ ์œผ๋กœ ๊ฐ์ง€
Pass-through ๋งˆ์šฐ์Šค ์ด๋™ ๋น ๋ฅด๊ณ  ์ง์ ‘์ ์ธ ๊ฐ’ ์ „๋‹ฌ, ํ•„ํ„ฐ ์—†์Œ

 

3. ๐Ÿง  InputAction ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ ์™„์ „ ์ดํ•ด

InputAction์˜ ์ž…๋ ฅ ์ด๋ฒคํŠธ๋Š” CallbackContext๋ฅผ ํ†ตํ•ด ๋‹ค์–‘ํ•œ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ“Œ CallbackContext๋ž€?

InputAction.CallbackContext๋Š” ์ž…๋ ฅ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ์ „๋‹ฌ๋˜๋Š” ๊ตฌ์กฐ์ฒด์ž…๋‹ˆ๋‹ค. ์ด ์•ˆ์—๋Š” ์–ด๋–ค ๊ฐ’์ด ๋ˆŒ๋ ธ๋Š”์ง€, ์–ด๋–ค ์ƒํƒœ์ธ์ง€ ๋“ฑ ์ค‘์š”ํ•œ ์ •๋ณด๊ฐ€ ๋‹ด๊ฒจ ์žˆ์Šต๋‹ˆ๋‹ค.


๐Ÿ“ ์ฃผ์š” ์†์„ฑ ์„ค๋ช…

์†์„ฑ ์„ค๋ช…
ctx.phase ์ž…๋ ฅ์˜ ํ˜„์žฌ ์ƒํƒœ (Started, Performed, Canceled)
ctx.ReadValue<T>() ์ž…๋ ฅ๊ฐ’์„ ์›ํ•˜๋Š” ํƒ€์ž…์œผ๋กœ ๋ฐ›์•„์˜ด (์˜ˆ: Vector2, float, bool)
ctx.control.name ์–ด๋–ค ์ž…๋ ฅ ์ปจํŠธ๋กค์ด ๋ˆŒ๋ ธ๋Š”์ง€ ํ™•์ธ ๊ฐ€๋Šฅ

โœ… phase๋ž€?

  • Started: ํ‚ค๊ฐ€ ๋ˆŒ๋ฆฌ๊ธฐ ์‹œ์ž‘ํ–ˆ์„ ๋•Œ ํ˜ธ์ถœ
  • Performed: ์‹ค์ œ ๋™์ž‘์ด ์™„๋ฃŒ๋˜์—ˆ์„ ๋•Œ ํ˜ธ์ถœ (ex. ์ŠคํŽ˜์ด์Šค๋ฐ” ๋ˆŒ๋Ÿฌ์„œ ์ ํ”„)
  • Canceled: ์ž…๋ ฅ์ด ํ•ด์ œ๋์„ ๋•Œ ํ˜ธ์ถœ (ex. ํ‚ค์—์„œ ์† ๋—Œ)
public void OnJumpInput(InputAction.CallbackContext context)
{
    if (context.phase == InputActionPhase.Started)
    {
        Debug.Log("์ ํ”„ ์‹œ์ž‘!");
    }
    else if (context.phase == InputActionPhase.Performed)
    {
        Debug.Log("์ ํ”„ ์‹คํ–‰!");
    }
    else if (context.phase == InputActionPhase.Canceled)
    {
        Debug.Log("์ ํ”„ ํ•ด์ œ!");
    }
}

โœ… ReadValue()๋ž€?

์ž…๋ ฅ์œผ๋กœ๋ถ€ํ„ฐ ๊ฐ’์„ ๋ฐ›์„ ๋•Œ ์‚ฌ์šฉ๋˜๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.

  • ReadValue<Vector2>() → ๋ฐฉํ–ฅํ‚ค ์ž…๋ ฅ
  • ReadValue<float>() → ๋งˆ์šฐ์Šค ํœ , ํŠธ๋ฆฌ๊ฑฐ ์••๋ ฅ
  • ReadValue<bool>() → ๋‹จ์ˆœ ๋ฒ„ํŠผ on/off
Vector2 movement = context.ReadValue<Vector2>();

โ€ป ์ œ๋„ค๋ฆญ ํƒ€์ž…์„ ์ž˜๋ชป ์ž…๋ ฅํ•˜๋ฉด ๋Ÿฐํƒ€์ž„ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์œผ๋‹ˆ ์ฃผ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

 

 

4. ๐Ÿงฉ PlayerInput ์ปดํฌ๋„ŒํŠธ์™€ InputAction ์—ฐ๋™

InputAction์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด Unity ์˜ค๋ธŒ์ ํŠธ์— ์‹ค์ œ ์ž…๋ ฅ์„ ๋ฐ›์„ ์ˆ˜๋‹จ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ”๋กœ ๊ทธ๊ฒƒ์ด PlayerInput ์ปดํฌ๋„ŒํŠธ์ž…๋‹ˆ๋‹ค.

PlayerInput์€ InputActionAsset๊ณผ ์—ฐ๋™๋˜์–ด ์ž…๋ ฅ์„ ๋ฐ›์•„ ๋™์ž‘์„ ์‹คํ–‰ํ•˜๋„๋ก ํ•ด์ฃผ๋Š” ์ค‘๊ณ„์ž ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.


โœ… PlayerInput์˜ ๊ตฌ์„ฑ ์š”์†Œ

ํ•ญ๋ชฉ ์„ค๋ช…
Actions ์‚ฌ์šฉํ•  InputActionAsset ํŒŒ์ผ ์ง€์ •
Default Map ์‹œ์ž‘ ์‹œ ํ™œ์„ฑํ™”ํ•  Action Map ์„ ํƒ (์˜ˆ: "Player")
Behavior ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ ๋ฐฉ์‹ ์„ ํƒ (SendMessage, UnityEvents, Invoke C# Events ๋“ฑ)
Camera Look ์ž…๋ ฅ์„ ์นด๋ฉ”๋ผ ๊ธฐ์ค€์œผ๋กœ ๋ณด์ •ํ•  ๊ฒฝ์šฐ ์—ฐ๊ฒฐ

โš™๏ธ Behavior ๋ฐฉ์‹ ๋น„๊ต

โ‘  SendMessage ๋ฐฉ์‹

  • Unity์˜ ๊ธฐ๋ณธ ๋ฉ”์‹œ์ง€ ์‹œ์Šคํ…œ ํ™œ์šฉ
  • ์•ก์…˜ ์ด๋ฆ„๊ณผ ๊ฐ™์€ ์ด๋ฆ„์˜ ํ•จ์ˆ˜๋ฅผ MonoBehaviour์—์„œ ์ž๋™์œผ๋กœ ์ฐพ์•„ ํ˜ธ์ถœ
void OnJump(InputValue value) { ... }
  • โœ… ๋น ๋ฅธ ๊ตฌํ˜„ ๊ฐ€๋Šฅ / โŒ ํผํฌ๋จผ์Šค ์ด์Šˆ ๊ฐ€๋Šฅ, ํ•จ์ˆ˜๋ช… ์ผ์น˜ ํ•„์ˆ˜

โ‘ก UnityEvents ๋ฐฉ์‹

  • ์ธ์ŠคํŽ™ํ„ฐ์—์„œ ์•ก์…˜๋ณ„๋กœ ํ•จ์ˆ˜ ์—ฐ๊ฒฐ ๊ฐ€๋Šฅ
  • ๋น„๊ฐœ๋ฐœ์ž๋„ ์„ค์ • ๊ฐ€๋Šฅํ•˜์—ฌ ํ˜‘์—…์— ์œ ๋ฆฌ
  • PlayerInputEvents ํƒญ์—์„œ ์ง์ ‘ ํ•จ์ˆ˜ ์—ฐ๊ฒฐ
// PlayerController.cs
public void OnMove(InputAction.CallbackContext context) { ... }

โ‘ข C# Events ๋ฐฉ์‹

  • ๊ฐ€์žฅ ์œ ์—ฐํ•˜๊ณ  ํผํฌ๋จผ์Šค๊ฐ€ ์ข‹์€ ๋ฐฉ์‹
  • ์ฝ”๋“œ์—์„œ ์ง์ ‘ InputAction์— ์ ‘๊ทผํ•˜๊ณ  .performed += ์œผ๋กœ ์—ฐ๊ฒฐ
playerInput.actions["Jump"].performed += ctx => Jump();
  • โœ… ์ฝ”๋“œ ๊ธฐ๋ฐ˜์œผ๋กœ ์ฒ ์ €ํžˆ ์ œ์–ด ๊ฐ€๋Šฅ / โŒ ์ดˆ๋ณด์ž์—๊ฒ ์ง„์ž…์žฅ๋ฒฝ ์žˆ์Œ

๐ŸŽฎ ์‹ค์Šต ์˜ˆ์‹œ: UnityEvents ๋ฐฉ์‹ ์—ฐ๊ฒฐ

  1. Player ์˜ค๋ธŒ์ ํŠธ์— PlayerInput ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€
  2. Actions์— .inputactions ํŒŒ์ผ ์—ฐ๊ฒฐ
  3. Behavior๋ฅผ Invoke Unity Events๋กœ ์„ค์ •
  4. PlayerController ์Šคํฌ๋ฆฝํŠธ์— ์ด๋ฒคํŠธ ํ•จ์ˆ˜ ์ž‘์„ฑ
  5. ์ธ์ŠคํŽ™ํ„ฐ์—์„œ ํ•ด๋‹น ์•ก์…˜์— ํ•จ์ˆ˜ ์—ฐ๊ฒฐ
public void OnMove(InputAction.CallbackContext context)
{
    Vector2 input = context.ReadValue<Vector2>();
    // ์ด๋™ ์ฒ˜๋ฆฌ
}

๐Ÿ” ํŒ: PlayerInput ์ž๋™ ์ƒ์„ฑ ๋ฐฉ์ง€ํ•˜๊ธฐ

PlayerInput ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ˆ˜๋™์œผ๋กœ ๋ถ™์—ฌ ์“ฐ๋Š” ๊ฒฝ์šฐ, ์ฝ”๋“œ๋‚˜ ๋‹ค๋ฅธ ๋งค๋‹ˆ์ €์—์„œ InputAction์„ ์ƒ์„ฑํ•˜๋ฉด ์ค‘๋ณต ์ƒ์„ฑ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•ญ์ƒ ํ•˜๋‚˜์˜ PlayerInput๋งŒ ์‚ฌ์šฉํ•˜๋„๋ก ์ฃผ์˜.

 

๋ฐ˜์‘ํ˜•