質問をすることでしか得られない、回答やアドバイスがある。

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

ただいまの
回答率

88.82%

UnityでRPCを使用して変数を受け渡したい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 420

sakuramoti

score 18

前提・実現したいこと

UnityでPhotonを使用して変数の受け渡しをしたいです。
流れとしては下記のように考えています。
・オブジェクトA,B(同一のUnityChanprefab)をネットワークインスタンスで生成。
・AがBに攻撃し、Bにヒットした際にAからRPCを用いてBに変数を受け渡し。
・Bが変数を受け取り、ダメージアニメーションを実行。

やってみたこと

1、UnityChanのprefab(両方とも同じもの)をネットワークインスタンス化し2つアプリを実行
2、ネットワークインスタンス化したUnityChanからRPCを用いて自分以外のターゲットで関数を実行

該当のソースコード(1の部分)

public class SimplePun : MonoBehaviourPunCallbacks
{ 
    // Start is called before the first frame update
    void Start()
    {
        PhotonNetwork.ConnectUsingSettings();
    }
    void OnGUI()
    {
        GUILayout.Label(PhotonNetwork.NetworkClientState.ToString());
    }

    public override void OnConnectedToMaster()
    {
        PhotonNetwork.JoinRoom("Room");
    }

    public override void OnJoinedRoom()
    {
      GameObject unityChan = PhotonNetwork.Instantiate("unitychan", Vector3.zero, Quaternion.identity, 0);
        //unityChan.GetComponent<UnityChanController>().enabled = true;
        //unityChan.GetComponent<Animator>().enabled = true;

    }
    public override void OnJoinRoomFailed(short returnCode, string message)
    {
        PhotonNetwork.CreateRoom("Room");
    }
}

該当のソースコード(2の部分)

private bool damageAnimFlag;
void Start () {
        damageAnimFlag = false;
              }
void Update()
    {
        if (photonView.IsMine)
        {
            Debug.Log(damageAnimFlag);//RPCのSetDamageAnimationが実行されてもずっとfalseのままになってしまう。
            if (damageAnimFlag == true)//damageAnimFlagにtrueが入ったら(RPCで値を渡したい)
            {
                playDamageAnimation();//ダメージを受けるアニメーションを実行
                damageAnimFlag = false;
            }
        }

void OnTriggerEnter(Collider other)
    {
        if (photonView.IsMine)
        {
            if (animator.GetBool("isAttack") == true && other.CompareTag("Player"))//プレイヤーの攻撃が他のプレイヤーにあったった時にDamageアニメーションを実行させるために値を送信。
            {
                photonView.RPC("SetDamageAnimation", RpcTarget.Others, true);
                this.setCapsuleCollider(false);
            }
        }
    }

    [PunRPC]
    void SetDamageAnimation(bool flag)
    {
        //Debug.Log("Execute RPC");
        this.damageAnimFlag = flag;
        //Debug.Log(damageAnimFlag);ここにはtrueがはいっている
    }

 結果

他のインスタンスの変数に値がうまく入らない。
SetDamageAnimationが実行されてdamageAnimFlagにはtrueが入っているのだが、update関数内のdamageAnimFlagにはtrueが入らず
falseのままダメージアニメーションが実行されない。

どなたか原因を教えていただけないでしょうか。
また、RPCを用いて他オブジェクトに変数を渡したい場合はどのようにすれば良いのでしょうか。

今回RPCを使用してダメージアニメーションを実行させようとしておりますが、
通常はどのように実装するのが良いかよければ教えていただけないでしょうか。
(足りない情報、必要な情報がございましたら補足いたしますのでよろしくお願いいたします。)

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

Photonやってたのは大分前なので細かい部分がうろ覚えです

このソースを見ると、受信側のphotonView.IsMine==trueということは、
送信側がphotonView.IsMine==falseのオブジェクトから送っていることになります

Photonって基本的にphotonView.IsMine==trueとなるクライアントが操作するべきなので、
このような送信方法はおかしいように思います

多分ですけど、SetDamageAnimationが実行されたインスタンスと
Updateで見ているインスタンスが異なっているせいに見えます

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/02/11 00:29 編集

    izmktr様 
    ご回答ありがとうございます。頂いた回答より自分の中で下記のように勘違いに気づきました。
    おそらくあっていると思うのですが間違いなどございましたらご指摘いただけないでしょうか。
    質問前の勘違いの状況
    ・端末AでDogというキャラクタをネットワークインスタンス化
    ・端末BでCatというキャラクタをネットワークインスタンス化

    ・端末AにはDogとCatが表示されている状態(DogがIsMine,Catが!IsMine)
    ・端末BにはCatとDogが表示されている状態(CatがIsMine,Dogが!IsMine)
     端末AでDogがCatに攻撃した際にRPCを用いて端末A内のCatの情報を更新できると思っていた。
     (RpcTarget.Othersが同端末のDog以外(Cat)と勘違いしていた。そのためDog(IsMine)がCatに攻撃した際にRpcで端末BのCatのdamageFlagをtrueセットしようとしていた。)

    実際は。。。。
    IsMineの中で実行しているため端末AのDogのdamageFlagがセットされるだけ。さらにその情報をRpctarget.Othersで渡しているので同期されるのはDogの情報だけ。
    今回質問の際には端末BのCatの情報をIsMineでUpdateをかけていたのでdamageFlagが更新されなかったということであっているでしょうか。

    質問後(勘違いに気づいた後):
    ・Rpctarget.ohtersは自分の端末以外で実行することに気づいた。
    よってソースコートを
    端末AのDogがCatに攻撃した際に,!IsMineであるCatのdamageFlagをtrueにする。
    その情報をRpcを用いて端末Bにて同期させる。というようにコードを書き換えました。

    わかったこと:
    Rpcは端末内のインスタンスごとではなく、クライアント(端末)単位で情報をやりとりするという理解でよろしいでしょうか。

    Photonまだ全然理解ができておらず変な勘違いを起こしてしまいました。
    それにも関わらず、おかしな部分に気づいてくださり感謝いたします。

    キャンセル

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

  • ただいまの回答率 88.82%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る