Is command only works on master (host) player? [Code attached]

Hello all,

I am running a shooting game where player have to command server to shoot, the server will execute the shoot, put value into shoot cd as [SyncVar].

The strange thing is that, only host can command fire, and it is affecting all the other client. So when host do a one click, all the client and the host itself will fire, the other client’s click have no effect.

Here is the code.

using System.Collections.Generic;
using System.Linq;
using Assets.scripts.Library;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Networking.NetworkSystem;

namespace Assets.scripts.Controllers
{
    public class PlayerController : NetworkBehaviour
    {
        public GunBarrelController Gbc;

        public GranadeLauncherController GlcLeft;
        public GranadeLauncherController GlcRight;

        [SyncVar]
        public float Health = 100;
        [SyncVar]
        public float Armor = 100;
        [SyncVar]
        private float fireRate = 5.0f;//Value for bar to track
        [SyncVar]
        private float _nextFire = 0.0f;

        ......

        void Start()
        {
            this._acceptInput = this.isLocalPlayer;
            if (this._acceptInput) {
                this._lockedTraget = new LockedTarget ();
                this._wm = WeaponMode.MainGun;
                CameraRegistry.activateGroupCamera (new string[]{"Main Camera", "GUI Camera"});
                this._detectedEnemies = Enumerable.Empty<GameObject> ();
                this.GetComponentInChildren<GunBarrelController> ().AcceptInput = true;

                Utilities.MakeGameObjectAndItsChildAstag(this.gameObject ,"Player");
                Utilities.MakeGameObjectAndItsChildAslayer(this.gameObject, "Player");
            } else {
                Utilities.MakeGameObjectAndItsChildAstag(this.gameObject ,"Enemy");
                Utilities.MakeGameObjectAndItsChildAslayer(this.gameObject, "Enemy");
            }
            ......
        }

        void Update()
        {
            if(this._acceptInput)
            {
                this.HandleUserInput();
                ......
            }
            ......
        }

        private void HandleUserInput()
        {
            ......

            this.CmdUserControlFire();

            ......
        }

......

        [Command]
        private void CmdUserControlFire()
        {
            if (Input.GetButton("Fire1") &&
                CameraStateController.CurrentCameraState != CameraStateController.CameraState.Support)
            {
                if (Time.time > this._nextFire && this._wm == WeaponMode.MainGun)
                {
                    this._nextFire = Time.time + this.fireRate;
                    this.Gbc.Fire();
                }
                else if (Time.time > this._nextFire && this._wm == WeaponMode.Missle)
                {
                    if (this._lockedTraget.GetLockedStatus() && this._lockedTraget.GetLockedTarget() != null)
                    {
                        this._nextFire = Time.time + this.fireRate;
                        this.Gbc.FireMissle(this._lockedTraget.GetLockedTarget());
                    }
                }
                else if (Time.time > this._nextFire && this._wm == WeaponMode.Smoke)
                {
                    this._nextFire = Time.time + this.fireRate;
                    this.GlcLeft.Fire();
                    this.GlcRight.Fire();
                }
            }
        }

......

    }
}

The Gbc(GunBarrelController) is a as child object on top of player’s gun , it is in charge of spawning bullets. It does not have player identity attached. Here is the implementation

using UnityEngine;
using UnityEngine.Networking;

namespace Assets.scripts.Controllers
{
    public class GunBarrelController : MonoBehaviour {

        public GameObject shell;
        public GameObject missle;
        public GameObject explosionParticle;
        public GameObject barrel;
        public float recoil = 1f;

        private bool recoilFlag = false;

        void FixedUpdate()
        {
            Ray ray = new Ray (this.transform.position, this.transform.forward);
            RaycastHit contact;
     
            if (Physics.Raycast (ray, out contact, Mathf.Infinity, Utilities.CameraLayerMask))
            {
                //                Debug.Log("Barrel Pointing: " + contact.point);
                GameObject.Find("HUD_Aim").GetComponent<bl_Hud>().HudInfo.Offset = contact.point;
            }
        }

        public void Fire()
        {
            Instantiate(this.shell, this.transform.position, this.transform.rotation);
            NetworkServer.Spawn(this.shell);
            if (this.explosionParticle != null)
            {
                Instantiate(this.explosionParticle, this.transform.position, this.transform.rotation);
                NetworkServer.Spawn(this.explosionParticle);
            }
        }

        public void FireMissle(GameObject target)
        {
            GameObject missileGo = (GameObject) Instantiate(this.missle, this.transform.position, this.transform.rotation);
            Guided_Missle gm = missileGo.GetComponent<Guided_Missle>();
            if (gm != null)
            {
                gm.SetTarget(target);
                NetworkServer.Spawn(missileGo);
            }
            if (this.explosionParticle != null)
            {
                Instantiate(this.explosionParticle, this.transform.position, this.transform.rotation);
                NetworkServer.Spawn(this.explosionParticle);
            }
        }
    }
}

They are the same player prefab, spawned by the unmodified network manager. Am I misunderstood command or is there something I am missing here?

Thank you very much for reading this, any help is greatly appreciated!

According to unity manual,

I still don’t see what I am doing wrong, does this means that the master player have ownership over all the other player’s player object in my case? How can I check that, it is unclear in the manual.

Saw a similar post,

It seems applicable to my scenario, but I did not disbale the player controller script and reactive them, they are active for all instance.

use OnStartLocalPlayer() instead of Start()

2 Likes

Thank you! That might be it, I never thought about that! Will have a try tonight.:wink: