Photon Server 유니티 멀티게임 만들기 webinar 2탄

GameManager.cs 소스입니다




using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
using Photon.Realtime;
using System;
using UnityEngine.UI;
using PN = Photon.Pun.PhotonNetwork;
using Random = UnityEngine.Random;

public enum State { None, QuickMatching, QuickMatchDone, RacingStart, RacingDone }

public class GameManager : MonoBehaviourPunCallbacks
{
public static GameManager Inst { get; private set; }
void Awake()
{
Inst = this;

ShowPanel("ConnectPanel");

PN.SendRate = 30;
PN.SerializationRate = 15;

if (autoJoin)
ConnectClick(null);

}

[Header("Debug")]
[SerializeField] bool autoJoin;
[SerializeField] byte autoMaxPlayer = 2;

[Header("Panel")]
[SerializeField] GameObject connectPanel;
[SerializeField] GameObject lobbyPanel;
[SerializeField] GameObject gamePanel;

[Header("Lobby")]
[SerializeField] Text quickMatchText;

[Header("Game")]
[SerializeField] Transform[] spawnPoints;
[SerializeField] UnityStandardAssets.Cameras.AutoCam autoCam;
[SerializeField] Text timeText;
[SerializeField] Text countdownText;

public State state;

public int GetIndex
{
get
{
for (int i = 0; i < PN.PlayerList.Length; i++)
{
if (PN.PlayerList[i] == PN.LocalPlayer)
return i;
}
return -1;
}
}
WaitForSeconds one = new WaitForSeconds(1);
int racingStartTime;



public void ShowPanel(string panelName)
{
connectPanel.SetActive(false);
lobbyPanel.SetActive(false);
gamePanel.SetActive(false);

if (panelName == connectPanel.name)
connectPanel.SetActive(true);
else if (panelName == lobbyPanel.name)
lobbyPanel.SetActive(true);
else if (panelName == gamePanel.name)
gamePanel.SetActive(true);
}


public void ConnectClick(InputField nickInput)
{
PN.ConnectUsingSettings();

string nick = nickInput == null ? $"Player{Random.Range(0, 100)}" : nickInput.text;
PN.NickName = nick;
}

public override void OnConnectedToMaster() => PN.JoinLobby();

public override void OnJoinedLobby()
{
ShowPanel("LobbyPanel");

if (autoJoin)
QuickMatchClick();
}

public void QuickMatchClick() 
{
if (state == State.None)
{
state = State.QuickMatching;
quickMatchText.gameObject.SetActive(true);
PN.JoinRandomOrCreateRoom(null, autoMaxPlayer, MatchmakingMode.FillRoom, null, null,
$"room{Random.Range(0, 10000)}", new RoomOptions { MaxPlayers = autoMaxPlayer });
}
else if (state == State.QuickMatching) 
{
state = State.None;
quickMatchText.gameObject.SetActive(false);
PN.LeaveRoom();
}
}

public override void OnJoinedRoom()
{
PlayerChanged();
}

public override void OnPlayerEnteredRoom(Player newPlayer)
{
PlayerChanged();
}

public override void OnPlayerLeftRoom(Player otherPlayer)
{
PlayerChanged();
}

void PlayerChanged()
{
if (PN.CurrentRoom.PlayerCount == autoMaxPlayer) { }
else if (PN.CurrentRoom.PlayerCount != PN.CurrentRoom.MaxPlayers)
return;

StartCoroutine(GameStartCo());
}

IEnumerator GameStartCo() 
{
print("GameStart");
ShowPanel("GamePanel");
SpawnCar();

yield return one;
countdownText.text = "3";
yield return one;
countdownText.text = "2";
yield return one;
countdownText.text = "1";
yield return one;
countdownText.text = "GO";
state = State.RacingStart;
racingStartTime = PN.ServerTimestamp;

yield return one;
yield return one;
countdownText.text = "";
}

void SpawnCar() 
{
GameObject carObj = PN.Instantiate("Car", spawnPoints[GetIndex].position, spawnPoints[GetIndex].rotation);
}

public void SetCamTarget(Transform target) 
{
autoCam.SetTarget(target);
}

void Update()
{
if (state == State.QuickMatching && PN.InRoom)
{
quickMatchText.text = $"{PN.CurrentRoom.PlayerCount} / {PN.CurrentRoom.MaxPlayers}";
}

TimeUpdate();
}

void TimeUpdate() 
{
if (state != State.RacingStart)
return;

TimeSpan elapsedTime = TimeSpan.FromMilliseconds(PN.ServerTimestamp - racingStartTime);
int milliseconds = (int)(elapsedTime.Milliseconds * 0.1f);
timeText.text = $"{elapsedTime.Minutes:D2}:{elapsedTime.Seconds:D2}:{milliseconds:D2}";

}
}










Car.cs 소스입니다



using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
using Photon.Realtime;

public class Car : MonoBehaviourPun
{
    [SerializeField] UnityStandardAssets.Vehicles.Car.CarController carController;

    void Start()
    {
        if (photonView.IsMine)
        {
            GameManager.Inst.SetCamTarget(transform);
        }
    }

void Update()
{
        if (photonView.IsMine)
        {
            if (GameManager.Inst.state == State.RacingStart)
            {
                float horizontal = Input.GetAxis("Horizontal");
                float vertical = Input.GetAxis("Vertical");
                float drift = Input.GetAxis("Jump");

                carController.Move(horizontal, vertical, vertical, drift);
            }
            else
                carController.Move(0, 0, 0, 1);
        }
    }
}