0 支持
(200 ポイント)

現在、VRゲームをMUNを使って通信をさせようとしています。

ですが、敵NPCの同期がうまくいきません。同期用コンポーネントは追加しています。

アニメーションは同期しているようなのですが、位置が同期されません。何か足りないのでしょうか?

敵NPCはPlayerタグが付いたオブジェクトを応用にしてあります。

敵NPCにつけているプレイヤーを追うコンポーネントは以下の通りです。

FolowPlayer.cs

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

using UnityEngine.AI;

public class FolowPlayer : MonoBehaviour {

    NavMeshAgent agent;

    GameObject player;

    ZombieScript zombi;

    public float stopDistance;

    // Use this for initialization

    void Start () {

        agent = GetComponent<NavMeshAgent>();

        player = GameObject.FindWithTag("Player");

        zombi = GetComponent<ZombieScript>();

}

// Update is called once per frame

void Update () {

       if (zombi.CanWalk)

        {

            // ゾンビがプレイヤーの方に向かっていく

            agent.destination = player.transform.position;   

        } 

}

}

回答 1

0 支持
(2.2k ポイント)
> player = GameObject.FindWithTag("Player");

> agent.destination = player.transform.position;  

この場合、各々のクライアントで最初に作成される、つまりは各々のプレイヤー自身の方向にしか移動しないので、MonobitTransformViewを追加しても同期が取れないのは当然のことです。

> player = GameObject.FindWithTag("Player");
の部分については、マルチプレイにおける、敵NPCが向かうべきプレイヤーの選定についてどのようにしたいか、考えがありますでしょうか。その内容によって回答は異なります。

> agent.destination = player.transform.position;  
の部分については、最低限
if( monobitView.isMine ) {
    agent.destination = player.transform.position;
}
としなければなりません。もっとも先に記述した通り、playerが適正値ではないので、この修正では不十分ですが。
(200 ポイント)
回答ありがとうございます。
ゾンビのプレイヤーの選定はランダムにしようと考えています。
よろしくお願いします。
(2.2k ポイント)
ゾンビのプレイヤー選定がランダム、であれば、「現在ゲームシーン上に存在するすべてのクライアントから」ランダムに探す必要があるため、FolowPlayer クラス内部を以下のように書き換えてください。

// MonobitView を参照するため、
// ベースクラスをMonobitEngine.MonoBehavior に書き換え
public class FolowPlayer : MonobitEngine.MonoBehaviour {
    NavMeshAgent agent;
    GameObject player;
    ZombieScript zombi;
    public float stopDistance;

    // 「個々が持つプレイヤー情報」とは別に
    // 「共有する移動先」を保存するための情報を確保
    Vector3 receivedPosition;

    // 「共有する移動先」を保存しているかの有無を表わすフラグ
    bool isReceivedPosition = false;

    void Start () {
        agent = GetComponent<NavMeshAgent>();

        // 移動先となるプレイヤーを、ゲームシーン内にある複数のプレイヤーから
        // ランダムに選択して移動する
        if( MonobitEngine.MonobitNetwork.isHost ) {
            // プレイヤー群を取得
            GameObject[] players = GameObject.FindGameObjectsWithTag("Player");

            // プレイヤー群の中の乱数要素を算出
            int pickup = Random.Range(0, players.Length-1);

            // 算出した乱数要素からプレイヤーを導出
            player = players[pickup];
        }

        zombi = GetComponent<ZombieScript>();
    }
   
    void Update () {
       // 移動先情報の送信
       if ( MonobitEngine.MonobitNetwork.isHost && player != null)
       {
            // プレイヤー自身の座標をRPCで共有する
            monobitView.RPC("OnFolllow", MonobitEngine.MonobitTargets.All,
                                         player.transform.position);
       }

       // 受信していた場合、ゾンビがプレイヤーの方に向かっていく
       if (zombi.CanWalk && isReceivedPosition && receivedPosition != null)
       {
           agent.destination = receivedPosition;
       }
    }

    // RPC の受信
    [MunRPC]
    void OnFollow(Vector3 position)
    {
        // 受信データの格納
        receivedPosition = position;
        isReceivedPosition = true;
    }
}
(200 ポイント)
上記のようにスクリプトを変えてみたところ、別の不具合が発生しました。
パソコンAとBで動かして、ゾンビは2体発生するようにしているのですが、

Aのパソコンでルームを作ると、ゾンビはちゃんとプレイヤーの方に向かってきて、攻撃のアニメーションもします。ですがルームに入ったBのパソコンでは1体目のゾンビのアニメーションが同期されません。

また、Bのパソコンでルームを作ると、ゾンビは発生したところから動きません。ルームに入ったパソコンAの方でも同様です。しばらくするとBのパソコンの片方のゾンビは攻撃のアニメーションを開始します。そのあと、どちらか一方を通信切断してもゾンビは動きません。また、もう一度ルームに入ると、新しくゾンビが生成されてしまします。

どちらのパターンでもプレイヤーが攻撃をするとちゃんとゾンビは消えます。
パソコンのスペックはBの方が高いです。

どうすればいいでしょうか。
よろしくお願いします。
(2.2k ポイント)
http://support.monobitengine.com/index.php?qa=1330&qa_1=mun%E3%81%AE%E9%80%9A%E4%BF%A1%E3%81%8C%E5%88%87%E6%96%AD%E3%81%95%E3%82%8C%E3%81%A6%E3%81%97%E3%81%BE%E3%81%86

上記トピックで「MonobitTransformView & MonobitAnimatorView を削除し、元に戻した」と返信されていますが、元に戻す際 MonobitView の ObservedComponentList に追加していますでしょうか?

上記トピックの内容が削除&再設定だけで解決するとは思えず、かつ「位置とアニメーションが同期しない」というところから考えると、同期処理自体が無効化されたままになっているのではないかということが懸念されます。
(200 ポイント)
回答ありがとうございます。
ちゃんとMonobitViewのObservedComponentRegistrationListに追加しています。
それを確認した後、もう一度実験を行った結果、不具合は変わりませんでした。
(2.2k ポイント)
大変申し訳ありませんが、「MonobitTransformView & MonobitAnimatorView を削除し元に戻しただけで修正される」件も「MonobitTransformView & MonobitAnimatorView を元に戻した状態でも位置&アニメーションが同期しない」件も、どういう原因か推察しかねますので、一度『現状のプロジェクト一式』を共有していただいて構いませんでしょうか?
(200 ポイント)
お手数をおかけして申し訳ありません。
下記がギガファイル便のURLになります。パスワードは0000です。
https://22.gigafile.nu/0207-f3f1395eb658cb0d2da135277c4a1b6b1

よろしくお願いします。
(2.2k ポイント)
編集
申し訳ありません。先の

http://support.monobitengine.com/index.php?qa=1330&qa_1=mun%E3%81%AE%E9%80%9A%E4%BF%A1%E3%81%8C%E5%88%87%E6%96%AD%E3%81%95%E3%82%8C%E3%81%A6%E3%81%97%E3%81%BE%E3%81%86

で記載したアニメーション制御について、isHost チェックがないとアニメーションフラグが各クライアントで上書きされてしまい同期しない場合がありますね。


       animator.SetBool("FallDown", true);

        if( MonobitEngine.MonobitNetwork.isHost ) {
           animator.SetBool("FallDown", true);
        }

にしなければなりませんし、

        animator.SetBool("Attack", true);

        if( MonobitEngine.MonobitNetwork.isHost ) {
            animator.SetBool("Attack", true);
        }

にしなければなりません。

ただ何度か試したものの、Zombie が動かない、位置同期しないという不具合は確認できません。ZombieRig5 以外(ZombieRig1~ZombieRig4, または ZombieRig6)をどこかで出現させているのであれば、ZombieRig5 と同じ構成にしなければならないので、適宜 ZombieRig5 に合わせる必要がありますが、そういった場合があるのでしょうか。
(200 ポイント)
回答ありがとうございます。
私の方でもいろいろと試した結果、ゾンビの位置の同期はできるようになりました。ありがとうございます。
ZombieRig5はヒエラルキーのzombieAppearance(4)にのみ設定されているのでそれ以外が出現することはないです。
ですが、プレイヤーに一定の距離に近づいたら、腕を振るアニメーションに代わるのですが、ホストは動くのにゲスト側のアニメーションが同期しません。
また、片方が退出すると、また新しくゾンビが生成されてしまうのですが、これは仕方ないのでしょうか?
よろしくお願いします。
(2.2k ポイント)
アニメーション同期しないのは良くわかりません。上記修正で「ルームホストが変更された場合など、例外的に同期しないケースがある」という問題が解決しますが、これ以外の例外的な要素があるとは思えないので…。

> 片方が退出すると、また新しくゾンビが生成されてしまうのですが、これは仕方ないのでしょうか?

これについては Assets/script/ApperScript.cs にある敵NPC出現処理について、

「ホスト」がどのクライアントであっても、敵の最大出現数を一定に保つ
http://bit.ly/2tvPU2M

のページに記載されているような「各クライアントで敵の最大出現数を一定に保つ」ように処理を加えなければなりません(そうしないと AppearScript.numberOfEnemys がホスト以外一定にならないので)

よって、さらに手順として以下の内容を組み込む必要があります。

1. zombieAppearance (4) に MonobitView コンポーネントを加える
2. AppearScript.cs について、MonobitEngine.MonoBehaviour を基底クラスに設定する

  public class AppearScript : MonobitEngine.MonoBehaviour

3. AppearScript クラスに MunRPC の受信メソッドを追加する

    [MunRPC]
    void SyncNumberOfEnemyes(int number)
    {
        numberOfEnemys = number;
    }

4.  AppearEnemy() メソッドに、monobitView.RPC() メソッドで 3. に定義した受信メソッドに RPC を飛ばす。

    // 敵出現メソッド
    void AppearEnemy()
    {

        // 出現させる敵をランダムに選ぶ
        var randomValue = Random.Range(0, enemys.Length);
        var randomenemys = enemys[randomValue];
        // 敵の向きをランダムに決定
        var randomRotationY = Random.value * 360f;

        //GameObject.Instantiate(enemys[randomValue], transform.position, Quaternion.Euler(0f, randomRotationY, 0f));
        GameObject newNPC = MonobitEngine.MonobitNetwork.Instantiate(randomenemys.name, transform.position, Quaternion.Euler(0f , randomRotationY, 0f), 0, null, true, false, true);

        numberOfEnemys++;
        monobitView.RPC("SyncNumberOfEnemyes", MonobitEngine.MonobitTargets.All, numberOfEnemys);
        elapsedTime = 0f;
    }
(200 ポイント)
回答ありがとございます。
上記のように処理をしたところ、NPCが生成されることはなくなりました。
ありがとうございました。
...