1인 개발/PushAndSlash

푸쉬앤슬래시 개인 프로젝트 21일차

잼잼재미 2024. 6. 11. 00:51

구현 내용


1. Ready 구현


 

  • 준비 완료 버튼을 클릭하면 Ready Text가 활성화
  • Room에 있는 두 player가 모두 Ready를 하면 멀티 대전 시작

 

RoomManger

private void Update()
{
    _myIsReady = _networkManager.IsReady;

    if (!_photonView.IsMine)
    {
        if (_enemyIsReady && !_isReady)
        {
            _isReady = true;
            _networkManager.EnemyReadyActive(true);
        }
        else if(!_enemyIsReady && _isReady)
        {
            _isReady = false;
            _networkManager.EnemyReadyActive(false);
        }

        if (_myIsReady && _enemyIsReady && !_isGameStart)
        {
            _isGameStart = true;
            Debug.Log("멀티 대전 시작!");
        }
    }
}

public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
    if (stream.IsWriting)
    {
        stream.SendNext(_myIsReady);
    }
    else
    {
        _enemyIsReady = (bool)stream.ReceiveNext();
    }
}

 

앞서 데이터를 전달한 방법인 OnPhotonSerializeView 함수를 통해 데이터를 서버에 전송했다. 그래서 동일하게 IsMine이 false인 RoomManager가 나의 Ready 상태와 적의 Ready 상태를 모두 관리할 수 있다. _myIsReady, _enemyIsReady bool 타입 변수가 모두 true일 때, 멀티 대전을 시작하도록 구현했다.

 

https://kkln2486.tistory.com/429

 

동기화

동기화 1.  PhotonView갱신이 빈번한 경우에 사용ex) 위치 이동, 상태 변경캐릭터의 동기화에 사용캐릭터에 PhotonView, PhotonScriptView 스크립트 추가  Setting OwnershipFixed : Ownership 고정Takeover : Ownership을

kkln2486.tistory.com

 

 

2. 채팅 구현


 

https://kkln2486.tistory.com/432

 

채팅 구현

구현 방법1. 기본 셋팅 Scroll View 생성   Scroll View의 Width, Height, Color, Anchors, Position 등 설정 (A 값 : 30)   Scrollbar Horizontal 삭제   Content의 자식에 Text(TMP) 추가하고 Font Asset, Font Size, Width 설정  

kkln2486.tistory.com

 

 

RoomController

private void SendChat()
{
    if (_photonView.IsMine)
    {
        string chat = PhotonNetwork.NickName + " : " + _networkManager.ChatInputText.text;
        _photonView.RPC("ChatRPC", RpcTarget.All, chat);
        _networkManager.ChatInputText.text = "";
    }
}

[PunRPC]
public void ChatRPC(string str)
{
    bool isInput = false;

    for (int i = 0; i < _chatTexts.Length; i++)
    {
        if (_chatTexts[i].text == "")
        {
            isInput = true;
            _chatTexts[i].text = str;
            break;
        }
    }

    if (!isInput)
    {
        for (int i = 1; i < _chatTexts.Length; i++)
        {
            _chatTexts[i - 1].text = _chatTexts[i].text;
        }

        _chatTexts[_chatTexts.Length - 1].text = str;
    }
}

 

RPC를 통해 Room에 있는 모든 Player가 위 함수를 함께 실행하도록 구현했다. InputField에 Text를 작성하고 버튼을 클릭하면 RPC가 실행된다.

 

 

RoomController

private void Start()
{
    if (_photonView.IsMine)
        _photonView.RPC("ChatRPC", RpcTarget.All, "<color=yellow>" + PhotonNetwork.NickName + "님이 참가하셨습니다.</color>");
}

public override void OnPlayerLeftRoom(Player otherPlayer)
{
    if (_photonView.IsMine)
        _photonView.RPC("ChatRPC", RpcTarget.All, "<color=yellow>" + otherPlayer.NickName + "님이 퇴장하셨습니다.</color>");
}

 

OnPlayerLeftRoom 함수는 Room에 Player가 나갈때 실행되는 콜백 함수다. Player가 나갈 때 나간 Player를 인자로 받아서 퇴장 문구를 출력하도록 했다. OnPlayerEnteredRoom 함수는 역시 Player가 들어올 때 실행되는 콜백함수이다. 이 함수를 사용하지 않고 Start문에서 실행한 이유는 앞서 구현한 방식 때문이다. 멀티 대전을 클릭하면 서버연결과 동시에 방생성 또는 참가를 하고, RoomController를 Instatiate 한다. 즉, Player가 입장과 동시에 RoomController가 생성되기 때문에 자기 자신이 입장한 것은 판단할 수 없었다. 

 

 

회고


오늘은 Room을 최종적으로 구현했다. 특히 채팅 구현이 어려웠는데 RPC에 대해서 공부하고, 블로그에 정리를 잘 해뒀기 때문에 구현할 수 있었다. 시간은 오래 걸렸지만, 충분한 공부가 없었다면 몇일은 더 소요될 것이라고 생각한다. 특히, 유투브 강의를 참고했는데, 내가 구현한 NetworkManager가 많이 달라서 코드를 알맞게 수정하느라 시간을 가장 많이 사용했다. 어떻게 구현은 했지만 생각보다 깔끔한 코드라는 생각은 들지 않았다. 하지만, 구현하는 방법에 대해서 확실히 이해하고 정리를 했기 때문에 다음 멀티 플레이 게임을 개발할 때, 조금더 정리된 코드를 작성할 수 있을 것 같다. 내일은 대망의 멀티 배틀맵에 접속하고 캐릭터 동기화를 진행하도록 하겠다!