Search AI

CJB_ny·2022년 6월 21일
0

2D_Project

목록 보기
17/23
post-thumbnail

delegate

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로 뱉어내야한다.

https://novlog.tistory.com/47

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에서 마지막 인자로 이렇게 줌

오류 있는데

지금 몬스터가 플레이어 인식도 다 하는데 대각선으로 움직임

이거 수정해야한다.

profile
공부 일기장으로 변해버린 블로그 (https://cjbworld.tistory.com/ <- 이사중)

0개의 댓글