Ssssong += Dev

[ProjectT] Message 교환 패턴 본문

카테고리 없음

[ProjectT] Message 교환 패턴

ssong_dev 2023. 4. 11. 19:53

 

카메라를 세팅했다. 돈스타브를 레퍼런스로 했다.

 

 

전회사에서 메시지 패턴을 이용한 이동 처리 구현을 공부했다.

공부용으로 남아 있는 코드가 있지만 이번 개인 프로젝트는 혼자서 해결책을 생각하기 힘든 구조들은 코드를 참고 하되,

최대한 내부 기능들을 스스로 구현하는 것을 목표로 하고 있기에 새로 짜고 있다.

 

 

 

메시지 교환 패턴을 구현하기에 앞서 Chat GPT에 기본 구조를 물어보고 최대한 가벼운 골격부터 잡기로 했다.

이후 내가 필요한 메시지 정보들을 채워넣으면 되겠지.

 

 

 

정말 간단한 큐 구조이다.

일단 이걸 그대로 MessageManager로 만들었다.

public class AIMessageManager : Singleton<AIMessageManager>
{
    private Queue<AIMessage> _messageQueue;

    public AIMessageManager()
    {
        _messageQueue = new Queue<AIMessage>();
    }

    public bool CheckExistMessage()
    {
        return _messageQueue.Count > 0;
    }

    public void EnqueueMessage(AIMessage message)
    {
        _messageQueue.Enqueue(message);
    }

    public AIMessage DequeueMessage()
    {
        if(_messageQueue.Count > 0 )
        {
            return _messageQueue.Dequeue();
        }
        else
        {
            return null;
        }    
    }

    public override void Dispose()
    {
        _messageQueue.Clear();
        _messageQueue = null;
    }
}

 

이동 시 Message로 필요한 값은 direction, position, target로만 세팅했다. 

public enum eAIMessageType
{
    None = 0,
    Move,
    Attack,
    Max
}

//캐릭터 이동 및 공격에 관한 메시지. 
public class AIMessage : Message
{
    //캐릭터 ID, 행동 타입, 방향 등 설정되어야 한다.
    public long ID;
    public Vector3 Direction;
    public Vector3 Position;
    public Vector3 Target;

    public AIMessage() 
    { 
        ID = 0;
        Direction = Vector3.zero;
        Position = Vector3.zero;
        Target = Vector3.zero;
        eAIMessageType = eAIMessageType.None;
    }

}

 

이제 조작키 입력 시 이렇게 메세지 큐에 메세지를 넣어 두고

private void InputMove(Vector3 direction)
        {
            AIMessage moveMessage = new AIMessage();
            moveMessage.Direction = direction;
            moveMessage.eAIMessageType = eAIMessageType.Move;
            AIMessageManager.Instance.EnqueueMessage(moveMessage);
        }

 

 

LateUpdate에서 프레임 당 하나씩 Dequeue되고 있다. 

 private void LateUpdate()
        {
            ProcessMessage();
        }

        //메세지 처리
        private void ProcessMessage()
        {
            if(AIMessageManager.Instance.CheckExistMessage())
            {
                AIMessage message = AIMessageManager.Instance.DequeueMessage();
                
                switch(message.eAIMessageType)
                {
                    case eAIMessageType.Move:
                        WorldView.PlayerCharacter.CharacterMove(message.Direction);
                        break;
                    case eAIMessageType.Attack:
                        break;
                }
            }
            
        }