본문 바로가기

Unity/Knowledge

델리게이트형 제너릭

변수에다가 함수를 더할 수 있는 이유

 

Public event Action <Vector2> OnMoveEvent;

스샷에서 보이는 것 처럼 OnMoveEvent는 변수인데 함수를 더하고 있다.

moveDirection의 값은 0이었지만 direction이 되었다.

 OnMoveEvent를 실행시킬때 받는 그 direction값 (InputValue)  =  Move메서드의 매개변수 direction 값

컨트롤러에서 실행시키전에 제발 좀 데려가달라는 뜻이다. (이걸 이해하기까지가 너무 오래걸렸다)

그리고 이 것은 메서드임에 불구하고 변수처럼 사용해서 OnMoveEvent에 더하고 있다.

Action은 델리게이트로 함수를 변수처럼 더할 수 있다.

 

정확히는 사용하기 쉽게 만든 델리게이트형 제너릭 형식이며, Action과 Func 있다

반환 값이 없으면 Action을 사용하고 있다면 Func를 사용

 

 

 

[ 델리게이트 응용해보기 ]

버튼을 클릭할 때마다 점수가 1 오르고, 이를 UI텍스트에 표시해보자

이것을 구현하는 것은 여러 방법이 있다.

 

① 버튼을 누를 때 점수가 오르게 하면서 UI를 수정하는 방법

② UI가 점수에게 계속 바뀌었는지 매 프레임마다 물어보는 방법

[델리게이트] 점수가 바뀌었는지 궁금한 인스턴스들을 등록하고, 바뀌었을 때 대상들에게 알려주는 방법

(ex. 등록하는애 ObjectMovement, 알려주는애 ObejctController)

 

세 가지 다 동작하겠지만, 동작이 복잡해질 수록 3번과 같이 구성하는 것이 가장 관리가 용이해진다

 

지금까지는 주로 ①번과 같은 매우 허접한 수준으로 해왔다

 

이번 문제에서는 ②번과 같이 버튼을 클릭했을 때 발생하는 함수를 적용해보자

ScoreBtton.cs는 버튼에, ScoreText.cs는 텍스트에 붙인다고 가정

 

 

[구현사항 1]

버튼을 클릭했을 때 발생하는 함수 적용하기

  • ScoreButton 스크립트를 생성하고 Button 타입의 필드 scoreButton를 추가하고, GetComponent로 연결
  • 점수를 저장하는 score 변수를 public으로 추가
  • score 필드를 1만큼 올리는 메소드 PointUp을 정의
  • Awake에서 ScoreButton의 Button.OnClick.AddListener 함수에 점수를 1점 올리는 PointUp을 연결

 

[구현사항 2]

버튼이 클릭되었을 때 발생하는 함수 추가하기

이번에는 점수를 표현하는TTextMeshProUGUI를 중앙상단에 배치하고,

버튼이 클릭되었을 때 이 값이 현재 점수를 표시하도록 구현

  • ScoreText 스크립트를 생성하고 ScoreButton 타입의 public 필드를 추가하고, 인스펙터 창에서 연결
  • TextMeshProUGUI 타입의 필드 ScoreText를 추가하고, GetComponent로 연결
  • ScoreButton.score를 가져와서 이를 ScoreText에서 표출하는 값으로 바꾸는 RefreshUI 메소드를 추가.
  • Awake에서 ScoreButton의 Button.OnClick.AddListener 함수에 RefreshUI 메소드를 추가로 연결

 


[ 델리게이트 변환 ]

ScoreButton 스크립트 수정

Action<int> OnScoreChanged를 만들어서, 점수가 변경될 때마다 호출

점수가 변경될 때 UnityAction<int>를 호출하여 현재 점수를 전달

 

ScoreText 스크립트 수정

ScoreButton의 OnScoreChanged에 RefreshUI 메소드를 추가하여 점수가 변경될 때마다 UI를 갱신