1
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?

UnityバージョンにおけるPhotonの同期処理の違いについて

Last updated at Posted at 2025-05-13

背景

以前のUnity(具体的にこのバージョンまでというのはわかりません)では、Photon側の処理が遅く、Start() メソッド内で PhotonNetwork.IsConnected を確認してからプレイヤーのプレハブを生成していました。この順序により、プレイヤーが正しく同期されるようになっていました。しかし、最近のUnityでは、マルチスレッドや非同期処理の挙動が変更され、PhotonとUnityの処理順がより独立化されました。その結果、Start() メソッド内でプレイヤーのプレハブを早い段階で生成すると、同期ずれが発生し、クライアント側のプレイヤーが見えなくなる(ホストのみ姿がみえ)という問題が発生しました。

(問題が発生したコード)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun; //Photonサーバーの情報を使用するため

public class GameManager : MonoBehaviourPunCallbacks //Photon viewやPunを使用するため
{
    public static GameManager Instance { get; private set; }
    [SerializeField] GameObject playerPrefab;

    // Start is called before the first frame update
    void Start()
    {
        if(PhotonNetwork.IsConnected && PhotonNetwork.IsMasterClient) //サーバーに接続していたら
        {
            if(playerPrefab!=null)
            {
                Vector3 spawnPosition = new Vector3(0f, 0f, 0f);
                PhotonNetwork.Instantiate(playerPrefab.name, spawnPosition, Quaternion.identity); //Photonを介した生成
            }
        }
    }
}

問題の詳細

最近のUnityでは、非同期処理がより厳密に管理されるようになり、Start() メソッド内でPhotonの同期処理を待たずにプレイヤーのプレハブが生成される場合があります。このタイミングの違いが原因で、プレイヤーオブジェクトの生成がPhotonのネットワーク同期処理よりも先行し、クライアント間で表示されるプレイヤーが異なったり、最終的にプレイヤーが見えなくなる現象が発生します。

影響

この問題は、プレイヤーが他のクライアントに表示されない、または同期が取れない状態を引き起こします。具体的には、プレイヤーの位置や動きが他のクライアントに反映されない、または一時的に見えなくなるという現象が発生します。特に、Start() メソッド内でプレイヤーオブジェクトの生成と同期処理を行う場合、この同期のタイミングが非常に重要です。

解決策

各クライアントが自分のプレイヤを生成する

具体的には、OnJoinedRoom() メソッド内で PhotonNetwork.IsMasterClient が false の場合に、SpawnPlayer() を呼び出して、各クライアントが自分のプレイヤーを生成しています。このようにすることで、マスタークライアント以外のクライアントがプレイヤーの生成を行うことになります。さらに、プレイヤーの生成に PhotonNetwork.Instantiate を使っているので、他のクライアントにもそのプレイヤーオブジェクトが同期されます。

(問題が発生したコードに付け足したコード)
    public override void OnJoinedRoom()
    {
        if (!PhotonNetwork.IsMasterClient)
        {
            // 各クライアントが自分のプレイヤを生成する
            SpawnPlayer();
        }
    }
    
    void SpawnPlayer()
        {
            if (playerPrefab != null && PhotonNetwork.IsConnected)
            {
                Vector3 spawnPosition = new Vector3(0f, 0f, 0f);
                PhotonNetwork.Instantiate(playerPrefab.name, spawnPosition, Quaternion.identity);
            }
        }

結論

UnityのバージョンにおけるPhotonとUnityの処理順の変更により、プレイヤーオブジェクトの生成タイミングが重要になりました。Start() メソッド内での処理順序に依存するのではなく、非同期処理を利用して適切な同期タイミングでプレイヤーオブジェクトを生成することが、同期ずれを防ぐために効果的な解決策となると思います。

1
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
1
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?