[Unity] 2D Player Controller
2D Player Controller
앞서 2월달에 올려놓은 플레이어 움직임에 대해서 많이 바뀌게 되어서 해당 내용을 포스팅하면서 공부할 예정이다.
위 내용에서는 기본적인 움직임을 다루었다면 이번에는 키입력, 움직임코드 분리(객체지향적), 자연스러운 움직임 표현등을 목표한다.
Controller
입력에 대한 일반화를 위해서 컨트롤러를 만들어 두고 활용하는 방법을 채택했다.
- 스크립터블 오브젝트를 상속받는 추상클래스
InputController
를 만든다. InputController
클래스 내부에 각 입력을 받는 추상메서드들을 작성한다.(점프, 공격, 움직임 등등..)InputController
를 상속받는PlayerController
클래스를 만든다.PlayerController
에서 추상화 메서드에 대한 정의를 작성한다.Controller
클래스를 만들고 public형식으로InputController
를 형식으로 받는다.
using UnityEngine;
/// <summary>
/// 입력/출력 컨트롤러 스크립터블 오브젝트
/// 아래에 입력에 필요한 추상화 메서드 작성..!
/// </summary>
public abstract class InputController : ScriptableObject
{
/// <summary>
/// 좌/우 움직임을 받는 메서드
/// </summary>
/// <returns></returns>
public abstract float RetrieveMoveInput();
/// <summary>
/// 점프 입력을 받는 메서드
/// </summary>
/// <returns></returns>
public abstract bool RetrieveJumpInput();
/// <summary>
/// 점프 홀드
/// </summary>
/// <returns></returns>
public abstract bool RetrieveJumpHoldInput();
/// <summary>
/// 공격 입력
/// </summary>
/// <returns></returns>
public abstract bool RetrieveAttackInput();
}
위처럼 입력에 대한 처리를 추상메서드로 작성하게 되면 해당 컨트롤러를 상속받는 컨트롤러는 메서드를 필수적으로 구현해야하기 때문에 빠지는 실수가 줄어든다.
그렇다면 왜 입력에 대한 처리를 일반화 하였는지에 대한 의문이 들 수 있다.
PlayerController
는 당연하게 상속받아서 사용하지만 일방적인 1차원 상속이라면 필요하지 않은 과정이기 때문이다.
하지만 AIController
로 구분하여 사용한다면 몬스터, NPC움직임 컨트롤러로 다앙하게 추상적 프로그래밍이 가능해진다.
using UnityEngine;
/// <summary>
/// 플레이어 입력 컨트롤러
/// </summary>
[CreateAssetMenu(fileName = "PlayerController", menuName = "inputController/PlayerController")]
public class PlayerController : InputController
{
public override float RetrieveMoveInput()
{
return Input.GetAxisRaw("Horizontal");
}
public override bool RetrieveJumpInput()
{
return Input.GetButtonDown("Jump");
}
public override bool RetrieveJumpHoldInput()
{
return Input.GetButton("Jump");
}
public override bool RetrieveAttackInput()
{
return Input.GetKey(KeyCode.Z);
}
}
해당 스크립트 자체를 스크립터블 오브젝트로 변환하여 사용가능하게 만들어 두고 각 객체에 컴포넌트에 삽입하여 관리한다.
using UnityEngine;
/// <summary>
/// 컨트롤러 컴포넌트
/// </summary>
public class Controller : MonoBehaviour
{
public InputController input = null;
}
위의 컴포넌트만 추가하고 나머지는 스크립터블 오브젝트를 삽입하여 관리하면 된다.
using UnityEngine;
/// <summary>
/// AI입력 컨트롤러(몬스터에 활용)
/// </summary>
[CreateAssetMenu(fileName = "AIController", menuName = "inputController/AIController")]
public class AIController : InputController
{
public override float RetrieveMoveInput()
{
return 1f;
}
public override bool RetrieveJumpInput()
{
return true;
}
public override bool RetrieveJumpHoldInput()
{
return false;
}
public override bool RetrieveAttackInput()
{
return false;
}
}
만약 controller를 가진 두가지의 객체가 있다고 해도 할당하는 오브젝트 성격에 따른 다른 입력처리를 할 수 있다.
댓글남기기