QUEST LAB

十二支 × 協力 × リアルタイムバトル『Play The Fox』を作っています。

開発開始1日目

なんと4人いないと満足にデバッグできない事に気づく。

これは困った。

ひとまずは、ウィンドウをたくさん立ち上げてごまかそう...。

 

フライング

開発1日目といったけど、実は結構フライングして作ったものがある。

現段階では、

  • プレイヤーが歩く
  • スキルっぽいものを発動する
  • 環境マークを配置する

くらいの事が出来る。

でも全部ローカルでの事だから、オンラインで同期しないといけない...。

ここまで1日1時間、1週間くらいで作った。

 

Gitを使おう

既に若干のプロジェクトがあるから、それをGitで管理できるようにする。

データ共有ができて、バックアップにもなる。

SourceTreeで、 新規追加 > 既存のローカルリポジトリを追加

今あるUnityのプロジェクトを選択する。

今回は同時に、BitBucketのリモートリポジトリも作った。

 

もう一台のパソコンでクローンしてみると、上手くいった。

やったね。

 

ゲームの流れを作る

ゲームの一連の流れを制御する、ゲームマネージャーを作成する。 ステートマシンもどき見たいな感じで作ろうと思ってる。 色々やってる内に、ステートは全部で次の7つになった。

Idle, Connecting, WaitingForOthers, Init, ReadyToStart. Arrange, Fight

基本的に左から順にステートが移動してく。 ArrangeとFightは時間経過でループする。

Photonでオンラインゲーム

Photonを使ってオンライン通信をする。 プレイヤーの位置同期をしたり出来る。

Photonは昔からあるけど、最近Photon2が出たらしい。 折角なので使ってみた。

結構苦戦したけれど、いい感じに設定をしたら何とか同期できた。

今のところ良さそうだ。 果たして、スマホで遠方の人とプレイするとどれくらいラグがあるのだろうか・・・。 頼む、耐えてくれ。

ちょっと備忘録。

 Photonの設定で苦戦したところを書いておく。

OnJoinedLobby()みたいなコールバック関数の使い方が分からなかった。

MonoBehaviourPunCallbacksを継承、 OnJoinedLobby()をオーバーライドして使う事でコールバックを使うらしい。

RoomInfoが定義されていないと言われた。
using Photon.Pun;
using Photon.Realtime;

の両方の名前空間を使う事で一応解決したが、よく分かってない。  

今回作ったゲームマネージャーの全文を載せておく。

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

public class GameManager : MonoBehaviourPunCallbacks
{
    public GameParameter gameParameter;

    private GameState state = GameState.Idle;
    private float timer = 5;

    private int ARRANGE_TIME = 5;
    private int FIGHT_TIME = 5;

    private StageMaker stageMaker;
    private GameObject[] fiveElements;

    public GameState State{
        get { return state; }
    }

    public float Timer{
        get { return timer; }
    }

    private void Start()
    {
        StartCoroutine(TimerCoroutine());
        ARRANGE_TIME = gameParameter.ARRANGE_TIME;
        FIGHT_TIME = gameParameter.FIGHT_TIME;

        stageMaker = GetComponent<StageMaker>();
    }

    private void Update()
    {
        switch(state){
            case GameState.Idle:
                InitConnectToLobby();
                state = GameState.Connecting;
                break;
            case GameState.Connecting:
                break;
            case GameState.WaitingForOthers:
                WaitingForOthers();
                break;
            case GameState.Init:
                Init();
                state = GameState.ReadyToStart;
                break;
            case GameState.ReadyToStart:
                
                break;
            case GameState.Arrange:
                if(hasArranged()){
                    InitFight();
                    state = GameState.Fight;
                }
                break;
            case GameState.Fight:
                if (hasArranged())
                {
                    InitArrange();
                    state = GameState.Arrange;
                }
                break;
        }
    }

    void InitConnectToLobby(){
        PhotonNetwork.ConnectUsingSettings();
        Debug.Log("Connectgin to master...");
    }

    public override void OnConnectedToMaster()
    {
        PhotonNetwork.JoinLobby();
        Debug.Log("Joining Lobby...");
    }

    public override void OnJoinedLobby()
    {
        Debug.Log("Joined Lobby!");
    }

    public override void OnRoomListUpdate(List<RoomInfo> roomList)
    {
        if(roomList.Count == 0){
            PhotonNetwork.CreateRoom("PlayRoom");
            Debug.Log("Created Room!");
        }else{
            PhotonNetwork.JoinRoom("PlayRoom");
        }
    }

    public override void OnJoinedRoom()
    {
        Debug.Log("Joined Room!");
        state = GameState.WaitingForOthers;
    }

    void WaitingForOthers(){
        string mode = PlayerPrefs.GetString("GameMode", "Solo");
        byte maxPlayerCount = 2;
        switch(mode){
            case "Solo":
                maxPlayerCount = (byte)2;
                break;
            case "Duo":
                maxPlayerCount = (byte)4;
                break;
        }
        if(PhotonNetwork.CurrentRoom.PlayerCount == maxPlayerCount){
            Debug.Log("Game Start!!");
            state = GameState.Init;
        }
    }

    private void Init()
    {
        PhotonNetwork.Instantiate(gameParameter.prefabs.characters.RAT.name, Vector3.zero, Quaternion.identity);
    }

    void InitArrange(){
        timer = ARRANGE_TIME;
    }

    bool hasArranged(){
        if(timer <= 0){
            return true;
        }
        return false;
    }

    void InitFight(){
        fiveElements = GameObject.FindGameObjectsWithTag("Element");
        //使用済みの環境を次に進める
        foreach(GameObject objElement in fiveElements){
            FiveElements element = objElement.GetComponent<FiveElements>();
            if (element.Element == ElementType.UsedTree
               || element.Element == ElementType.UsedWater
               || element.Element == ElementType.UsedGround)
            {
                element.AdvanceElement();
            }
        }
        timer = FIGHT_TIME;

        //ステージに配置された環境マーカーを環境に変換する
        stageMaker.MakeElementFromMarker();
    }

    bool hasFight(){
        if(timer <= 0){
            return true;
        }
        return false;
    }

    IEnumerator TimerCoroutine(){
        while (true)
        {
            yield return new WaitForSeconds(1);
            if (timer >= 0)
            {
                timer -= 1;
            }
        }
    }

}