これちのPost-it

技術ネタをペラペラと

SharingWithUNET サンプルでクライアント側のみ弾が前へ進まない問題

HoloToolkit-Unity-Example にある SharingWithUNET サンプルを実機で動作させたらクライアント側でのみ弾が前に進まなず空中で静止するバグ?を発見(サーバ側では弾がちゃんと前に進む)

その原因となる問題のコードがこちら

  • MixedRealityToolkit-Unity/Assets/HoloToolkit-Examples/SharingWithUNET/Scripts/PlayerController.cs github.com
        [Command]
        void CmdFire()
        {
            Vector3 bulletDir = transform.forward;
            Vector3 bulletPos = transform.position + bulletDir * 1.5f;

            // The bullet needs to be transformed relative to the shared anchor.
            GameObject nextBullet = (GameObject)Instantiate(bullet, sharedWorldAnchorTransform.InverseTransformPoint(bulletPos), Quaternion.Euler(bulletDir));
            nextBullet.GetComponentInChildren<Rigidbody>().velocity = bulletDir * 1.0f;
            NetworkServer.Spawn(nextBullet);

            // Clean up the bullet in 8 seconds.
            Destroy(nextBullet, 8.0f);
        }

        public void OnInputClicked(InputClickedEventData eventData)
        {
            if (isLocalPlayer)
            {
                CmdFire();
            }
        }

NetworkServer.Spawn(nextBullet); でクライアント側でも球が表示されるわけですが、velocity はクライアント側に引き継がれませんのでクライアント側でも別に velocity を与えてあげる必要があります

そこでクライアント側ではクライアント側で Instantiate をした object に対して velocity を与えてあげる RpcShoot() をサーバでの処理である CmdFire() のあとに呼び出します

       [Command]
        void CmdFire()
        {
            Vector3 bulletDir = transform.forward;
            Vector3 bulletPos = transform.position + bulletDir * 1.5f;

            // The bullet needs to be transformed relative to the shared anchor.
            GameObject nextBullet = (GameObject)Instantiate(bullet, sharedWorldAnchorTransform.InverseTransformPoint(bulletPos), Quaternion.Euler(bulletDir));
            nextBullet.name = "Bullet";
            Vector3 velocity = bulletDir * 5.0f;
            nextBullet.GetComponentInChildren<Rigidbody>().velocity = velocity;
            NetworkServer.Spawn(nextBullet);
            RpcShoot(nextBullet, velocity);

            // Clean up the bullet in 8 seconds.
            Destroy(nextBullet, 8.0f);
        }

        [ClientRpc]
        void RpcShoot(GameObject obj, Vector3 velocity)
        {
            obj.GetComponentInChildren<Rigidbody>().velocity = velocity;
        }

これで無事にクライアント側でも弾が出現した後に前へ進むようになりました