Skip to content

4월1주차

kimhaneu1 edited this page Apr 9, 2025 · 14 revisions

현재까지 진행사항

Addressable로 관리하는 데이터가 로딩이 완료되면 Toutch To Start 가 깜밖이고 GameReadyScene이 로드됩니다. 게임시작버튼을 누르면 유저가 네트워크상에 접속하고 랜덤방을 찾습니다. 만약 없으면 랜덤방을 생성하고 2명이 모이면 게임씬으로 전환을 합니다. 게임씬으로 전환할때 유저의 Json파일을 역직렬화하여 UI_GameScene이 이름과 최근승률을 표시합니다.


포톤 Fun을 써본적이 있어서 쓰려했으나 더이상 업데이트를 하지 않고 포톤 퓨전이 상위호환이랑서 새롭게 공부해봤다.
포톤 Fusion은 실제 서버를 배포하는것이 아니라 내부적으로 권한을 가지고 있는 클라이언트를 서버처럼 이용하는 방식이다.
권한이 있는 유저의 데이터를 수십바이트의 작은 패킷으로 묶어 tick단위의 시간마다 동기화하는 방식이다.
권한은 포톤 퓨전에 의해 랜덤으로 결정되며 권한이 있는 유저가 네트워크에 연결이 끊길경우 다른 유저로 권한이 옮겨간다.

GameServerManager 클래스

public class GameServerManager : SimulationBehaviour, INetworkRunnerCallbacks
{
    [SerializeField]
    private GameObject _playerCharacter;

    private PlayerRef _localPlayerRef;

    private static GameServerManager _gameServer;
    public static GameServerManager GameServer { get { Init(); return _gameServer; } }

    public static void Init()
    {
        if (_gameServer == null)
        {
            Debug.Log("게임서버매니저 초기화");
            GameObject go = GameObject.Find("@GameServerManager");
            if (go == null)
            {
                go = new GameObject { name = "@GameServerManager" };
                go.AddComponent<GameServerManager>();
                go.AddComponent<NetworkRunner>();
                go.GetComponent<GameServerManager>()._playerCharacter = Managers.Resource.Load<GameObject>("@PlayerCharacter");
            }

            DontDestroyOnLoad(go);

            // 초기화
            _gameServer = go.GetComponent<GameServerManager>();
        }
    }

    public void OnPlayerJoined(NetworkRunner runner, PlayerRef player)
    {
        Debug.Log("OnPlayerJoined 호출");
        if (player == runner.LocalPlayer)
        {
            _localPlayerRef = player;
        }

        int playerCount = runner.ActivePlayers.Count();

        Debug.Log($"Player joined: {player.PlayerId} / Total players: {playerCount}");

        if (playerCount == 2)
        {
            Debug.Log("2 players joined. Starting game!");
            StartOmok();
        }
    }

    private void StartOmok()
    {
        Debug.Log("StartOmok 호출");
        if (Runner.IsSceneAuthority)
        {
            Runner.LoadScene("GameScene", LoadSceneMode.Single);
        }

    }

    public void OnSceneLoadDone(NetworkRunner runner)
    {
        Debug.Log("OnSceneLoadDone 호출");
        NetworkObject localPlayer = runner.Spawn(_playerCharacter, Vector3.zero, Quaternion.identity, _localPlayerRef);
        runner.SetPlayerObject(_localPlayerRef, localPlayer);
    }
}

DataManager 클래스

public interface ILoader<Key, Value>
{
    Dictionary<Key, Value> MakeDict();
}

public class DataManager
{
    public Dictionary<int, Data.TestData> TestDic { get; private set; } = new Dictionary<int, Data.TestData>();

    public void Init()
    {
        TestDic = LoadJson<Data.TestDataLoader, int, Data.TestData>("TestData").MakeDict();
    }

    private Loader LoadJson<Loader, Key, Value>(string path) where Loader : ILoader<Key, Value>
    {
        TextAsset textAsset = Managers.Resource.Load<TextAsset>(path);
        return JsonConvert.DeserializeObject<Loader>(textAsset.text);
    }
}

  • google연동을 하고 firebase를 쓸건데 데이터베이스 Json파일을 역직렬화해서 객체로 저장하기위한 매니저를 만들었습니다.

매니저에서 딕셔너리의 키랑 벨류값 설정이 잘못되어 수정중입니다.

직렬화를 하기 위해서는 [Serializable] 어트리부트를 클래스 위에 붙여줘야 합니다.

TestData

namespace Data
{
    #region TestData
    [Serializable]
    public class TestData
    {
        public string Name;
        public int BlackGamePlayed;
        public int WhiteGamePlayed;
        public int BlackWins;
        public int WhiteWins;
    }

    [Serializable]
    public class TestDataLoader : ILoader<int, TestData>
    {
        public List<TestData> tests = new List<TestData>();

        public Dictionary<int, TestData> MakeDict()
        {
            Dictionary<int, TestData> dict = new Dictionary<int, TestData>();
            foreach (TestData testData in tests)
                dict.Add(testData.BlackGamePlayed, testData);

            return dict;
        }
    }
    #endregion
}


앞으로는 게임을 진행하는 과정을 상태패턴으로 만들어서 GameScene에서 돌리고 플레이어가 알을 두는 행위를 하면 UI에서 이벤트기반으로 UI를 업데이트해주는 콜백함수를 구독을 할것입니다.

Clone this wiki locally