3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Photon Fuisonをunityで採用しつつ、Playfab Multiplayer上(Playfabの中でマルチプレイ用のサーバーサービス)を実現するための導入をイメージしやすく(自分が)するために、擬人化(おっさん化)して、文章にしたためてみました。

Last updated at Posted at 2023-02-06

Playfab、Photonfusionを全く知らないおっさん49歳がだいたい1ヶ月ぐらいで、遠回りしまくってみた内容をまとめてみました。

主な役割を担うおっさん達

:man:Server
:man:Agent
:man:Heartbeat
:man:Build
:man:Client
5つのおっさんが必要

ローカルでの開発に必要なおっさん達

:man:Docker Desktop
:man:LocalMpsAgent

おっさん達の詳細

Server
Playfab Multiplayer Playfab内で、複数人数用のサーバーのサービスを用意してくれるおっさん
Agent
「Playfab Multiplayerおっさん」を呼び出すためのおっさん
Heartbeat
「Serverのおっさん」と、「Agentのおっさん」との間で、生きてますかぁ?生きてますよぉの生存確認を伝えるおっさん
Build
画面は持たずClientのリクエストに応じて返事をするおっさん Unity で書いたServerの役割を持つ部分 FuisonのRunnerのインスタンを持ち回し、StartSimulationで、環境を作る
Client
エンドユーザーの端末に入りユーザーからのボタンや十字キーからの命令を一旦受け取ったり、画面を生成するおっさん

下記が実際のコードUnityで適当にobjectを作りスクリプトを当てれば大丈夫

namespace Fusion.Sample.DedicatedServer
{
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.SceneManagement;
    using PlayFab;
    using Fusion.Photon.Realtime;
    using Fusion.Sockets;
    using System.Collections;
    using System.Threading.Tasks;
    using System.Net;
    
    public class ServerManager : MonoBehaviour
    {
        [SerializeField] private NetworkRunner _runnerPrefab;
        public bool Debugging = true;
        
        public void Awake()
        {
            Debug.Log("ServerManager Awake");
            if (CommandLineUtils.IsHeadlessMode() == false) {
                SceneManager.LoadScene((int)SceneDefs.CLIENTMENU, LoadSceneMode.Single);
                return;
            }
        }
        void Start () {
            Debug.Log("ServerManager Start");
            PlayFabMultiplayerAgentAPI.Start();
            PlayFabMultiplayerAgentAPI.IsDebugging = Debugging;
            PlayFabMultiplayerAgentAPI.OnServerActiveCallback += OnServerActive;
            StartCoroutine(ReadyForPlayers());
        }
        
        IEnumerator ReadyForPlayers()
        {
            Debug.Log("ServerManager ReadyForPlayers");
            yield return new WaitForSeconds(.5f);
            PlayFabMultiplayerAgentAPI.ReadyForPlayers();
        }
    
        private void OnServerActive()
        {
            Debug.Log("ServerManager OnServerActive");
            
            //For Fusion
            StartFusion();
        }
        async void StartFusion() {
          Debug.Log("ServerManager StartFusion");
          Application.targetFrameRate = 30;

          var config = DedicatedServerConfig.Resolve();
          Debug.Log(config);
          
          var runner = Instantiate(_runnerPrefab);
          var result = await StartSimulation(
            runner,
            config.SessionName,
            config.SessionProperties,
            config.Port,
            config.Lobby,
            config.Region,
            config.PublicIP,
            config.PublicPort
          );
          
          if (result.Ok) {
            Log.Debug($"Runner Start DONE");
          } else {
            Log.Debug($"Error while starting Server: {result.ShutdownReason}");
            Application.Quit(1);
          }
        }

        private Task<StartGameResult> StartSimulation(
          NetworkRunner runner,
          string SessionName,
          Dictionary<string, SessionProperty> customProps,
          ushort port,
          string customLobby,
          string customRegion,
          string customPublicIP = null,
          ushort customPublicPort = 0
        ) {

          Debug.Log("StartFusion StartSimulation");
          
          // Build Custom Photon Config
          var photonSettings = PhotonAppSettings.Instance.AppSettings.GetCopy();

          if (string.IsNullOrEmpty(customRegion) == false) {
            photonSettings.FixedRegion = customRegion.ToLower();
          }

          // Build Custom External Addr
          NetAddress? externalAddr = null;

          if (string.IsNullOrEmpty(customPublicIP) == false && customPublicPort > 0) {
            if (IPAddress.TryParse(customPublicIP, out var _)) {
              externalAddr = NetAddress.CreateFromIpPort(customPublicIP, customPublicPort);
            } else {
              Log.Warn("Unable to parse 'Custom Public IP'");
            }
          }
          
          return runner.StartGame(new StartGameArgs() {
            SessionName = SessionName,
            GameMode = GameMode.Server,
            SceneManager = runner.gameObject.AddComponent<NetworkSceneManagerDefault>(),
            Scene = (int)SceneDefs.CLIENTGAME,
            SessionProperties = customProps,
            Address = NetAddress.Any(port),
            CustomPublicAddress = externalAddr,
            CustomLobbyName = customLobby,
            CustomPhotonAppSettings = photonSettings,
          });
        }
    }
}

Buildした後は、linuxの場合、Dockerを使ってイメージ化が必要
docker build -t [yourplayfabuserIDforRegistory]/[yourgamename]:1.0
docker push [yourplayfabuserIDforRegistory]/[yourgamename]:1.0

Pushすると、PlayfabMultiplayerの管理画面でOSをLinuxにした場合に選択できる。

Dockerfile

# base image
FROM ubuntu:bionic

# installRUN apt-get --yes update && \
    apt-get --yes clean && \
    apt-get --yes install sudo

# add and setup fusion user
RUN useradd -m fusion && \
    echo "fusion:fusion" | chpasswd && \
    adduser fusion sudo

# copy server binary files
COPY --chown=fusion:fusion bin /home/fusion/bin

# set permissions on entrypoint
RUN chmod +x /home/fusion/bin/entrypoint.sh

# execute container as this user
USER fusion

# setup start scriptENTRYPOINT ["/home/fusion/bin/entrypoint.sh"]

# Fusion Server Port
EXPOSE 27015/udp

一旦疲れたのでここで終了。
他の方がめっちゃ丁寧に文章を書いてくれてるんだなと、改めてすごいと思う。
いつもありがとうございます。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?