実現したいこと
以下のオンラインゲームを制作したいです。
~スタート画面~
スタートボタン
~ゲーム画面~
①タイマーの開始
②プレイヤーのオブジェクトを生成
③1秒間隔で上から黒いボールが降ってきて
それに触れると、触れたプレイヤーに+1点
④タイマーの終了
⑤次の画面へ遷移
~リザルト画面~
①画面に得点を表示
②戻るボタンを押すと、
得点とタイマーをリセットしてから
スタート画面に遷移。
発生している問題・分からないこと
ゲームをまた最初から始めるとき
1回目に獲得した得点と経過して0になったタイマーを最初の設定に戻したい。
該当のソースコード
using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; public class シーン移動 : MonoBehaviour { void Start() { } public void StartButton() { SceneManager.LoadScene("ゲーム画面"); } public void BackButton() { SceneManager.LoadScene("スタート画面"); } }
using Photon.Pun; using UnityEngine; using UnityEngine.UI; using ExitGames.Client.Photon; public class スコアボード用スクリプト : MonoBehaviour { public Text text; private void Start() { } void Update() { if (text == null) return; // 追加: 安全チェック text.text = ""; foreach (var p in PhotonNetwork.PlayerList) { var props = p.CustomProperties; int score = props.ContainsKey("Score") ? (int)props["Score"] : 0; string lastHit = props.ContainsKey("LastHit") ? (string)props["LastHit"] : ""; text.text += $"{p.NickName} : {score}点 {lastHit}\n"; } } }
using Photon.Pun; using Photon.Realtime; using UnityEngine; using ExitGames.Client.Photon; using System.Globalization; public class HitManager : MonoBehaviourPun { public static HitManager Instance; void Awake() { if (Instance == null) { Instance = this; } } [PunRPC] public void NotifyHit(int actorNumber) { Player targetPlayer = null; foreach (var p in PhotonNetwork.PlayerList) { if (p.ActorNumber == actorNumber) { targetPlayer = p; break; } } if (targetPlayer == null) return; // 2. そのプレイヤーの Score を +1 する Hashtable props = new Hashtable(); int currentScore = 0; if (targetPlayer.CustomProperties.ContainsKey("Score")) { currentScore = (int)targetPlayer.CustomProperties["Score"]; } props["Score"] = currentScore + 1; // 3. CustomProperties を更新して全員に同期 targetPlayer.SetCustomProperties(props); Debug.Log($"Score updated for {targetPlayer.NickName}: {currentScore} -> {currentScore + 1}"); } }
using ExitGames.Client.Photon; using Photon.Pun; using Photon.Realtime; using UnityEngine; using UnityEngine.UI; public class 制限時間スクリプト : MonoBehaviourPunCallbacks { [SerializeField] private float limitSeconds = 60f; [SerializeField] private Text timerText; private const string StartTimeKey = "StartTime"; private bool isFinished = false; // void Start() // 修正前 public override void OnJoinedRoom() // // 修正 ルーム参加後に開始時刻を設定 { if (PhotonNetwork.IsMasterClient) { Hashtable hash = new Hashtable(); hash[StartTimeKey] = PhotonNetwork.Time; PhotonNetwork.CurrentRoom.SetCustomProperties(hash); } } void Update() { if (PhotonNetwork.CurrentRoom == null) // // 修正 CurrentRoomがnullなら止める return; if (PhotonNetwork.CurrentRoom.CustomProperties == null) // // 修正 念のためnullチェック return; if (!PhotonNetwork.CurrentRoom.CustomProperties.ContainsKey(StartTimeKey)) return; double startTime = (double)PhotonNetwork.CurrentRoom.CustomProperties[StartTimeKey]; double elapsed = PhotonNetwork.Time - startTime; double remain = limitSeconds - elapsed; if (remain < 0) remain = 0; if (timerText != null) // // 修正 timerText未設定でも落ちないようにする timerText.text = Mathf.CeilToInt((float)remain).ToString(); if (!isFinished && remain <= 0) { isFinished = true; TimeUp(); } } void TimeUp() { Debug.Log("制限時間終了"); } }
PUN2スクリプト
1using Photon.Pun; 2 3using Photon.Realtime; 4using UnityEngine; 5 6// MonoBehaviourPunCallbacksを継承して、PUNのコールバックを受け取れるようにする 7public class SampleScene : MonoBehaviourPunCallbacks 8{ 9 public static int A; 10 private void Start() 11 { 12 13 // プレイヤー自身の名前を"Player"に設定する 14 PhotonNetwork.NickName = "Player"; 15 16 17 18 19 // PhotonServerSettingsの設定内容を使ってマスターサーバーへ接続する 20 PhotonNetwork.ConnectUsingSettings(); 21 22 23 24 25 26 27 28 29 } 30 31 // マスターサーバーへの接続が成功した時に呼ばれるコールバック 32 public override void OnConnectedToMaster() 33 { 34 // "Room"という名前のルームに参加する(ルームが存在しなければ作成して参加する) 35 PhotonNetwork.JoinOrCreateRoom("Room", new RoomOptions(), TypedLobby.Default); 36 } 37 38 // ゲームサーバーへの接続が成功した時に呼ばれるコールバック 39 public override void OnJoinedRoom() 40 { 41 42 PhotonNetwork.NickName = "Player" + PhotonNetwork.LocalPlayer.ActorNumber + ""; // 43 44 45 46 47 48 49 GameObject bullet = PhotonNetwork.Instantiate("Sphere", transform.position, Quaternion.identity); 50 51 52 bullet.GetComponent<Destry>().ownerActorNumber = PhotonNetwork.LocalPlayer.ActorNumber; 53 54 55 } 56 57 58 private void Update() 59 { 60 if (Input.GetKeyDown(KeyCode.Space)) 61 { 62 PhotonNetwork.Instantiate("Black", new Vector3(0,5,0), Quaternion.identity); 63 64 65 66 67 } 68 } 69 70 71 72}
試したこと・調べたこと
- teratailやGoogle等で検索した
- ソースコードを自分なりに変更した
- 知人に聞いた
- その他
上記の詳細・結果
結果はできませんでした。
補足
特になし
【リザルト表示スクリプト】
using UnityEngine;
using UnityEngine.UI;
using Photon.Pun;
public class bbb : MonoBehaviour
{
public Text text;
void Update()
{
if (text == null) return; // 追加: 安全チェック
text.text = "";
foreach (var p in PhotonNetwork.PlayerList)
{
var props = p.CustomProperties;
int score = props.ContainsKey("Score") ? (int)props["Score"] : 0;
string lastHit = props.ContainsKey("LastHit") ? (string)props["LastHit"] : "";
text.text += $"{p.NickName} : {score}点 {lastHit}\n";
}
}
}
【スクリプトの置き場所】
スタート画面…
シーン移動
ゲーム画面…
スコアボード用スクリプト…ゲーム画面シーンのテキストにアタッチします。
PUN2スクリプト
HitManager
制限時間スクリプト
リザルト画面…
シーン移動
リザルトスクリプト