C# delegate는 C/C++의 함수 "포인터"와 비슷한 개념으로 메서드 파라미터와 리턴 타입에 대한 정의를 한 후, 동일한 파라미터와 리턴 타입을 가진 메서드를 서로 호환해서 불러 쓸 수 있는 기능이다.
예를 들면, 아래 RunDelegate 델리게이트는 입력 파라미터가 int 하나이고 리턴 값이 없는 메서드를 가리킨다.
RunThis() 메서드와 RunThat()메서드는 모두 int 파라미터 하나에 리턴 값이 없는 메서드이므로, RunDelegate의 함수 형식(prototype)과 맞으므로 이 delegate를 사용할 수 있다.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.IO;
namespace TestProject
{
class Program
{
// 1. delegate 선언
private delegate void RunDelegate(int i);
private void RunThis(int val)
{
// 콘솔출력 : 1024
Console.WriteLine("{0}", val);
}
private void RunThat(int value)
{
// 콘솔출력 : 0x400
Console.WriteLine("0x{0:X}", value);
}
public void Perform()
{
// 2. delegate 인스턴스 생성
RunDelegate run = new RunDelegate(RunThis);
// 3. delegate 실행
run(1024);
//run = new RunDelegate(RunThat); 을 줄여서
//아래와 같이 쓸 수 있다.
run = RunThat;
run(1024);
}
}
class Program2
{
static void Main(string[] args)
{
Program p = new Program();
p.Perform();
}
}
}
델레게이트와 프로토 타입이 같아야 한다.
https://blog.naver.com/hana100494/221409320935
이 블로그 참고
2. Action
Action 이름; 의 형태로 선언한다. 단어 뜻 그대로 일종의 '동작'이므로 반환 값 없이 연결 된 일련의 함수들을 실행한다. 전체적인 사용 방법은 event와 동일하지만 네임스페이스에 using System;를 넣어주어야 쓸 수 있다
using System;
public class PrintManager : MonoBehaviour
{
public Action<string> PrintAllEvent;
void Start()
{
PrintAllEvent += PrintA;
PrintAllEvent += PrintB;
PrintAllEvent?.Invoke("print out!");
}
void PrintA(string s)
{
Debug.Log("A is " + s);
}
void PrintB(string s)
{
Debug.Log("B is " + s);
}
}
3. Func
Func<T, TResult> 이름; 의 형태로, Action과 달리 반환값이 존재하며 맨 마지막 매개변수 TResult가 반환값의 형태이다. 하나의 반환값을 가지기 때문에 여태까지 예시로 다룬 옵저버 패턴보다, 람다식을 활용해 빠르고 간단하게 특정 값을 얻어낼 때 주로 사용한다.
예제에서 사용한 PrintName Func은 string값인 s변수를 입력받아 일정 형식의 string값을 반환값으로 받는 람다식이 연결되어 있다. 그리고 로그를 통해 그 값을 출력한다.
public class PrintManager : MonoBehaviour
{
public Func<string, string> PrintName;
void Start()
{
PrintName = (s) => { return "my name is "+ s; };
Debug.Log(PrintName("john"));
}
}
ObjectManager의
Find의 인자에 Func<GameObject, bool> condition
condition(obj)는 겜오브젝트 인자로 받아서 결과를 bool로 뱉어내야한다.
Func같은 경우는 위에서 설명한것 처럼 람다 형식으로 받을 수 있다.
그래서 Managers.Object.Find ( (go) => {} ) 이렇게 가능한거임.
우리가 오른쪽에서 결국 이렇게 만들어준 람다식을 왼쪽의 public GameObject Find에다가 condition으로 넘겨준 것이다.
우리가 람다로 만들어준 조건에 따라서 condition이 실행이 되면서 람다 조건에 부합하는 녀석이 있으면
왼쪽 47번째 줄 return obj; 하게된다.
찾게되면 이것을
_target으로 받아준다. => 이작업을 while문 안에서 코루틴으로 1초마다 실행하게 된다.
현재 위치는 CellPos이다.
그래서 destPos를 _target != null일 경우 destPos구한다음에
AStar를 돌리는데 (조금 수정 해주었었다 목적지에 물체가 있더라도)
시작, 목적지, ignoreDestCollision : true 라고 해주었는데
FindPath 의 destPos에 어떤 물체가 있다고 하더라도 충돌로 인식하지 않고 길을 찾겠다라는 의미이다.
MapManager에서 마지막 인자로 이렇게 줌
지금 몬스터가 플레이어 인식도 다 하는데 대각선으로 움직임
이거 수정해야한다.