Search code examples
c#network-programmingunity-game-enginegame-engineunity3d-unet

How to send commands from non - player objects UNET


I am unable to send commands from my gun prefabs in my game. How can I send commands from non-player game objects? Every time I try to send a command, I get an error. I do not want to move my shooting scripts from my guns to my player, as this method will require me to change my game drastically.

My Shooting Script:

[Command]
    void CmdOpenFire(){


    if (Physics.Raycast(camTransform.TransformPoint(startPosition), camTransform.forward, out hit, range)){
        gunsMasterScript.CallEventShotDefault(hit.point, hit.transform);
        if (hit.transform.parent != null) {
            if (hit.transform.parent.CompareTag ("Enemy")) {

                gunsMasterScript.CallEventShotEnemy (hit.point, hit.transform.parent);
            }
        }


        if (hit.transform.tag == "Player") {
            gunsMasterScript.CallEventShotEnemy (hit.point, hit.transform);
        }
    }

}

My shooting Detection script:

public PlayerManager_AmmoBox localPlayerTester;
public GunsManager_GunsAmmo gunsAmmo;
public GunsManager_GunsMaster gunMaster;
float nextAttack;
public float attackRate = 0.5f; 
Transform myTransform;
public bool isAutomatic = true;
public bool hasBurstFire;
bool isBurstFireActive;
public string attackButtonName;
public string reloadButtonName;
public string burstFireButtonName;
NetworkIdentity netID;

// Use this for initialization
void OnEnable () {
    if (transform.root != null) {
        if (transform.root.GetComponent<PlayerManager_AmmoBox> () != null) {
            localPlayerTester = transform.root.GetComponent<PlayerManager_AmmoBox> ();
        }
    }
    SetInitialReferences ();

}

// Update is called once per frame
void Update () {
    if (localPlayerTester != null) {
        CheckIfWeaponShouldAttack ();
        CheckForReloadRequest ();
        CheckForBurstFireToggle ();
    }

}
void SetInitialReferences(){
    netID = GetComponent<NetworkIdentity> ();
    myTransform = transform;
    gunMaster = transform.GetComponent<GunsManager_GunsMaster> ();
    gunsAmmo = transform.GetComponent<GunsManager_GunsAmmo> ();
     gunMaster.isGunLoaded = true; 
}


void CheckIfWeaponShouldAttack(){

    if (gunMaster != null) {
        if (Time.time > nextAttack && Time.timeScale > 0 && myTransform.root.CompareTag ("Player") && gunMaster.isGunLoaded) {


                if (isAutomatic && !isBurstFireActive) {
                if (Input.GetButton (attackButtonName)) {
                    AttemptAttack ();
                }

            } else if (isAutomatic && isBurstFireActive) {
                if (Input.GetButtonDown (attackButtonName)) {
                    StartCoroutine (RunBurstFire ());

                }

            } else if (!isAutomatic) {

                if (Input.GetButton (attackButtonName)) {
                    AttemptAttack ();
                }
            }

        }
    }
}

void AttemptAttack(){
    nextAttack = Time.time + attackRate;
    if (gunMaster.isGunLoaded) {

        gunMaster.CallEventPlayerInput ();

    } else {

        gunMaster.CallEventGunNotUsable ();
    }
}

Solution

  • Commands have to be called on the gameobject (which has a NetworkBehavior) that is associated with a certain player. Thus, I do not believe they can be called from non-player objects.

    However, you could make the gun script communicate to the script that is on the player (the one which is a NetworkBehavior that is associated with a player's connection). This would cause the error to stop. (This communication could be done through SendMessage or just regular function calls to the player object.)

    In conclusion, currently, UNet does not allow Commands from non-player objects, so some change will need to be done to the layout of your player/gun scripts in order to use commands. However, this could be done with only a few lines of code by just making the gun script "talk to" the player script -- the script inheriting from NetworkBehavior that is associated with a player's connection.

    More information on commands can be seen here: https://docs.unity3d.com/ScriptReference/Networking.CommandAttribute.html