작성
·
213
0
c++ 만 주로 공부하다가 c#과 유니티를 공부한지 얼마 안된 학생입니다.
대부분은 문법이 비슷해서 쉽게 이해하고 넘어갔지만
역시 delegate쪽에서 약간 애를 먹고 있습니다.
제가 아직 콜백과 코루틴의 개념이 제대로 잡혀있지않습니다..
각설하고
InputManager를 작성하실 때
delegate인 action과 invoke를 이용해서 작성하셨는데요
제가 예전에 만들어봤던 InputManager는 키 입력을
if(PressedA)
b_A = true;
이런 방식으로 Manager에서 bool값을 이용해서 바꿔주었습니다.
그리고 그걸 이용하는 player에서는 해당 bool값을 검사해 해당 프레임에서 눌렸는지를 우선 검사한뒤
해당 동작에 대한 처리를 했습니다.
이와다르게 구독을 통해서 구현하셨는데요
제가 아직 c#을 안해서 개념이 잘 안잡혀있기 때문에
싱글턴으로 InputManager를 바로 Player에서 Using 한 다음 delegate 구독을 하지 않고
메소드만 따로 빼서 검사할 수 있는 방법도 있는데 (위에 언급한 방법)
어떤 이점이 있어서 구독과 invoke를 써서 구현하셨는지 궁금합니다.
답변 2
2
말씀하신 것처럼 상태를 변화시키고,
그 상태를 Update할 때마다 체크해서 하는 방법도 당연히 가능하고
실제로 UnityEngine.Input 클래스의 경우 (유니티에서 기본 제공하는 인풋 관련 클래스)
그런 식으로 되어 있으니 딱히 문제가 되는 방법은 아닙니다.
C#의 delegate는 C++로 치면 [함수 포인터] 혹은 [std::function] 이라고 생각하시면 됩니다.
delegate의 invoke하는 것은 함수 포인터를 호출하는 개념인데,
Observer 패턴의 전형적인 호출 방식이라고 볼 수 있습니다.
구독 방식의 장점은 우리가 궁금해 하는 이벤트가 발생하면
처음에 등록한 함수로 알려준다는 것에 의의가 있습니다. (ex. 클릭이 발생하면! -> 이 함수로 알려줘)
구독이라고 하니 잡지에 비유할 수 있는데,
관심있는 잡지를 구독 신청하면,
그 잡지의 신간이 발행할 때 알아서 폰으로 알림이 오거나 집으로 배송될 겁니다.
이게 바로 Observer 패턴이라고 볼 수 있습니다.
반면 말씀하신 b_A = true로 세팅할 경우
외부 Update 안에서 매 틱마다 한 번씩 b_A의 상태를 확인하는 일종의 폴링(Polling) 방식으로 구현하게 됩니다.
비유하자면 본인이 직접 매일마다 편의점에 가서,
잡지가 새로 발행되었는지를 확인하는 셈이 됩니다.
신간이 없더라도 매일 매일 확인해야 한다는 번거로움이 생기겠죠.
Input 뿐만 아니라 다양한 경우에 폴링 vs 이벤트 중 선택해야 하는 상황이 오는데,
양쪽의 장단점을 대략적으로 생각해보자면
간~혹 일어나는 경우 이벤트 방식이 좋고,
어차피 자주 일어나는 이벤트라면
굳이 함수 호출을 하지 않고 필요한 쪽에서 상태 확인을 하는 것이 좋겠죠.
결국 위 코드에서 InputManager를 delegate로 구현한 것은
그냥 중앙 시스템(InputManager)에서 틱마다 한 번만 상태를 확인해서
클릭 등의 이벤트가 발생하면 해당 이벤트가 발생한 사실을 전체로 뿌리기 위함입니다.
그런데 물론 clicked = true와 같은 상태로 저장하고,
외부에선 이 clicked 여부를 체크하더라도 딱히 문제가 되진 않습니다. (단 clicked 체크를 매 틱마다 해줘야겠죠)
감사합니다.
0