share facebook facebook twitter menu hatena pocket slack

2020.02.12 WED

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

出野 皓士

WRITTEN BY 出野 皓士

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} に移譲されました");
    }
}

元記事はこちら

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

出野 皓士

出野 皓士

2019/02入社。Android アプリ開発がメイン。将来の記憶喪失に備えて技術記事を書く。

cloudpack

cloudpackは、Amazon EC2やAmazon S3をはじめとするAWSの各種プロダクトを利用する際の、導入・設計から運用保守を含んだフルマネージドのサービスを提供し、バックアップや24時間365日の監視/障害対応、技術的な問い合わせに対するサポートなどを行っております。
AWS上のインフラ構築およびAWSを活用したシステム開発など、案件のご相談はcloudpack.jpよりご連絡ください。