Help us understand the problem. What is going on with this article?

Unity/PUN2 による RequestOwnership() で OnOwnershipRequest コールバックが呼ばれない!?ときにチェックすること

悩んでいたこと

タイトルの通り。
Unity/PUN2(Photon)によるリアルタイム通信を実装していて、ネットワークオブジェクトの所有権の操作をしていました。

PUN2で始めるオンラインゲーム開発入門【その5】
https://connect.unity.com/p/pun2deshi-meruonraingemukai-fa-ru-men-sono5

PhotonView.RequestOwnership()すればいいよ、ということはわかったのですが、どうしてもコールバックの OnOwnershipRequest() が呼ばれずに悩んでいました。

何が原因だったか

これを書いていませんでした。。。
PhotonNetwork.AddCallbackTarget(this);
IPunOwnershipCallbacks を実装したオブジェクトをコールバックに登録するコードを書く必要がありました。。。

これ、API リファレンス以外のところに書かれてなくない!?
(公式のチュートリアルにすら書いてない)

このフォーラムの投稿から見つけました。。。

PUN v2 Ownership Callbacks
https://forum.photonengine.com/discussion/13494/pun-v2-ownership-callbacks

同じことで悩んでいる人が1分でも早く解決にたどり着けるよう、記事にしておこうと思い立った次第です。

まとめ - OnOwnershipRequest コールバックを使いたい場合のネットワークオブジェクトの所有権移譲の実装方法

  1. 権限移譲の対象にしたいネットワークオブジェクトの PhotonView の所有権オプションを Request にする。
  2. IPunOwnershipCallbacks インターフェースを実装したスクリプトを作り、OnOwnershipRequest, OnOwnershipTransfer コールバックを実装する
  3. そのオブジェクトを Photon のコールバックに登録するため、PhotonNetwork.AddCallbackTarget(this)する。そのスクリプトが MonoBehaviour を継承しているなら、OnEnable() でやるのが吉。(this は IPunOwnershipCallbacks を実装したオブジェクト)
  4. そのスクリプトをゲームオブジェクトにアタッチする。(使いたいシーンで)
  5. 所有権を要求したいタイミングで、そのオブジェクトの PhotonView.RequestOwnership() を呼ぶ。

ちなみに、コールバック登録を解除したい場合はPhotonNetwork.RemoveCallbackTarget(this)です。MonoBehaviour なら OnDisable() で。

参考

こういうスクリプトを書いてゲームオブジェクトにアタッチしておくと動きます。

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

public class PunCallback : MonoBehaviour, IPunOwnershipCallbacks
{
    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {

    }

    void OnEnable() {
        PhotonNetwork.AddCallbackTarget(this);
    }

    void OnDisable() {
        PhotonNetwork.RemoveCallbackTarget(this);
    }

    // 所有権のリクエストが行われた時に呼ばれるコールバック
    void IPunOwnershipCallbacks.OnOwnershipRequest(PhotonView targetView, Player requestingPlayer)
    {
        // 自身が所有権を持つインスタンスで所有権のリクエストが行われたら、常に許可して所有権を移譲する
        if (targetView.IsMine)
        {
            bool acceptsRequest = true;
            if (acceptsRequest)
            {
                targetView.TransferOwnership(requestingPlayer);
            }
            else
            {
                // リクエストを拒否する場合は、何もしない
            }
        }
    }

    // 所有権の移譲が行われた時に呼ばれるコールバック
    void IPunOwnershipCallbacks.OnOwnershipTransfered(PhotonView targetView, Player previousOwner)
    {
        string id = targetView.ViewID.ToString();
        string p1 = previousOwner.NickName;
        string p2 = targetView.Owner.NickName;
        Debug.Log($"ViewID {id} の所有権が {p1} から {p2} に移譲されました");
    }
}
Idenon
記憶を無くした未来のオレへのメモを書く
cloudpack
Amazon Web Services (AWS) の導入設計、環境構築、運用・保守をサポートするマネジドホスティングサービス
https://cloudpack.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした