🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Photon Cloud

Photon Cloudは、オンラインゲーム開発向けネットワークエンジン。リアルタイムマルチプレイ通信のプラットフォームであるPhotonの一つです。ネットワーク通信によるオンラインゲームを開発・運営するために必要なツールがサーバー環境に構築されています。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

2回答

2839閲覧

PUN2のPunTurnManagerを使ってターン開始時の処理を実装したい

shio01

総合スコア1

Photon Cloud

Photon Cloudは、オンラインゲーム開発向けネットワークエンジン。リアルタイムマルチプレイ通信のプラットフォームであるPhotonの一つです。ネットワーク通信によるオンラインゲームを開発・運営するために必要なツールがサーバー環境に構築されています。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2022/02/23 08:17

PUN2のPunTurnManagerを使って、ターン制のゲームを作成しています。
現在、下記のコードでテストしておりターンが始まった時の処理を実装しようと考えています。

簡単な流れは
「ルームに2人目が入室」
→「ターンが開始」
→「ボタンをクリックで自分のターン終了」 or 「10秒経過で互いのターンが終了」
→「次のターンが開始」
となっています。

C#

1using Photon.Pun; 2using System.Collections; 3using System.Collections.Generic; 4using UnityEngine; 5using Photon.Realtime; 6using Photon.Pun.UtilityScripts; 7 8public class Turn : MonoBehaviourPunCallbacks, IPunTurnManagerCallbacks 9{ 10 private PunTurnManager turnManager; 11 12 void Start() 13 { 14 //マスターサーバーへ接続 15 PhotonNetwork.ConnectUsingSettings(); 16 } 17 18 public override void OnConnectedToMaster() 19 { 20 //Roomという名前のルームを作成する、既存の場合は参加する 21 PhotonNetwork.JoinOrCreateRoom("Room", RoomOPS, TypedLobby.Default); 22 23 } 24 public override void OnJoinedRoom() 25 { 26 27 //ルーム参加時、ルーム人数の上限ならゲーム開始 28 if (PhotonNetwork.CurrentRoom.PlayerCount == PhotonNetwork.CurrentRoom.MaxPlayers) 29 { 30 Debug.Log("人数が揃いました"); 31 photonView.RPC(nameof(GameStart), RpcTarget.All); 32 } 33 } 34 35 static RoomOptions RoomOPS = new RoomOptions() 36 { 37 MaxPlayers = 2, 38 IsOpen = true, //部屋に参加できるか 39 }; 40 41 42 [PunRPC] 43 void GameStart() 44 { 45 if (PhotonNetwork.IsMasterClient) 46 { 47 Debug.Log("私がマスター"); 48 this.turnManager.BeginTurn();//turnmanagerに新しいターンを始めさせる 49 } 50 } 51 52 public void Awake() 53 { 54 this.turnManager = this.gameObject.AddComponent<PunTurnManager>(); 55 this.turnManager.TurnManagerListener = this; 56 this.turnManager.TurnDuration = 10f; 57 } 58 59 public void OnPlayerFinished(Player photonPlayer, int turn, object move) 60 { 61 } 62 public void OnPlayerMove(Player photonPlayer, int turn, object move) 63 { 64 } 65 public void OnTurnBegins(int turn)//3 ターンが開始した場合 66 { 67 Debug.Log("今、" + turn + "ターン目が開始しました"); 68 } 69 public void OnTurnCompleted(int obj)//4ターン終了時に呼ばれるメソッド 70 { 71 Debug.Log("ターン終了時処理"); 72 this.turnManager.BeginTurn(); 73 } 74 public void OnTurnTimeEnds(int turn)//5 タイマーが終了した場合 75 { 76 Debug.Log("時間切れ"); 77 this.turnManager.BeginTurn(); 78 } 79 public void OnClickButton()//ボタンをクリックで自分のターン終了 80 { 81 Debug.Log("ボタンクリック"); 82 this.turnManager.SendMove(1, true); 83 } 84} 85

そこで、OnTurnBeginsの中にターン開始時処理を書こうと思ったのですが
10秒経過でターンが切り替わるときに限り、何度もOnTurnBeginsOnTurnTimeEndsが呼ばれているようです。
以下が、そのログです。イメージ説明

これではターン開始時の処理が何度も動いてしまうので困っています。
原因もしくは対策がわかる方がいたら教えてください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

OnTurnTimeEnds() の中で BeginTurn() を呼んでいるからです。PunTurnManager で言う「ターン」とは一般的に連想する「ターン」とは違って「全てのプレイヤーが行動して初めて 1 ターンが終了する」という扱いです。

従って、「私の番だけど時間切れになったからあなたの番になる」という意味でこの OnTurnTimeEnds() を使うことはできません。そういう時間切れは自分で作る必要があります。

こういう事情があって OnTurnTimeEnds() の中で BeginTurn() を呼ぶことはないだろう、と Photon の開発者は考えてこういう仕様にしてるのかな?と思います。

OnTurnTimeEnds() の中で BeginTurn() を呼ぶと、ログ上は何回も呼ばれるけど、次のような挙動をします。

Player A, B がいて、A さんが先攻として、A さんが何も操作しなくてタイムアウトするとターンが終わってまた A さんの番から始まる。

こういう挙動は普通ではないですよね。なのでプロトタイプを作っている時はタイムアウトなしか、上の変な挙動でお茶を濁しておいて、本格的に作るぞ、ってなった時に一般的なタイムアウト処理を自分で作ることになります。

投稿2022/02/23 09:30

bboydaisuke

総合スコア5308

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shio01

2022/02/23 10:47

回答ありがとうございます。 PunTurnManagerのターンの仕様を理解できました。 タイムアウトの処理は自作しようと思います。
guest

0

OnTurnTimeEnds中のthis.turnManager.BeginTurn()はターン数を増やすだけなのでthis.turnManager.SendMove(null, true);で相手のターンに移りそうです。
時間切れのログに引数のturnも出してみると状態が分かると思います。

投稿2022/02/23 09:19

shiena

総合スコア1827

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shio01

2022/02/23 10:45 編集

回答ありがとうございます。 OnTurnTimeEndsが呼ばれた時点で勝手にターンが終了しているものと勘違いしていました。 コメントのように書き換えたところ想定内の動きになりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問