Clicks over Network.

Hello,

Noobie here trying to understand the flow and such of Multiplayer. I have a few things going on that “sort of” work. However I CAN"T wrap my head around “targeting” a monster on the server via client.

Spawner Script :

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;

public class Spawn : NetworkBehaviour {


    public int numOfGhost=1;
    public int timer;
    public bool died;


    // Use this for initialization
    void Start () {
        GetComponent<SpriteRenderer> ().color = new Color (255, 255, 255, 0);
    }
  
    // Update is called once per frame
    void Update () {
  

        if (died == true) {
            timer += 1;
            if (timer >= 200&&numOfGhost<=1) {
                died = false;
                timer = 0;
                numOfGhost = 1;
                var spawnLoc = new Vector3 (this.transform.position.x, this.transform.position.y, this.transform.position.z);
                var enemy = (GameObject)Instantiate (Resources.Load ("Ghost"), spawnLoc, Quaternion.identity);
                enemy.transform.SetParent (transform);
                NetworkServer.Spawn (enemy);

            }
        }


    }


    public override void OnStartServer(){
        var spawnLoc = new Vector3 (this.transform.position.x, this.transform.position.y, this.transform.position.z);
        var enemy = (GameObject)Instantiate (Resources.Load("Ghost"), spawnLoc, Quaternion.identity);
        enemy.transform.SetParent (transform);
        NetworkServer.Spawn (enemy);

    }


    public void HasDied(){
        died = true;
    }
        }

This is just to test a mob who has died and changing sprites. The same code is used to spawn “Bat” 's instead in where I am trying to test the targeting.

Bat Script :

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;

public class Bat : NetworkBehaviour {
  
    public GameObject bar;
    [SyncVar]
    float max_Health=100f;
    [SyncVar]
    float cur_Health=0f;

    public GameObject barr;


    // Use this for initialization
    void Start () {
        //bar = GameObject.Find ("HPFront");
        cur_Health = max_Health;
        barr = GetComponentInChildren<MobHp> ().gameObject;
        }
  
    // Update is called once per frame
    void Update () {
  
    }

    [ClientRpc]
    public void RpcSetHPBar(float myHP){
    barr.transform.localScale = new Vector3 (Mathf.Clamp (myHP, 0f, 1f), barr.transform.localScale.y, barr.transform.localScale.z);
    }

    /*void DecreaseHP(){
        cur_Health -= 1;
        float calc_HP = cur_Health / max_Health;
        RpcSetHPBar (calc_HP);
    }*/
    [Command]
    public void CmdDecreaseHP(){
        cur_Health -= 1;
        float calc_HP = cur_Health / max_Health;
        RpcSetHPBar (calc_HP);
    }

    //void OnMouseDown(){
    //    DecreaseHP ();

    //    }
}

Player Target Script :

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;

public class pTarget : NetworkBehaviour {

//    public GameObject tTarget;
    public Camera pCam;

    // Use this for initialization
    void Start () {
        pCam = GetComponentInChildren <Camera> ();

    }
  
    // Update is called once per frame
    void Update () {
        if (isLocalPlayer) {
            if (Input.GetMouseButtonDown (0)) {
                Vector3 mousePos = Input.mousePosition;
                mousePos.z = 10;
                Vector3 screenPos = pCam.ScreenToWorldPoint (mousePos);
                RaycastHit2D hit = Physics2D.Raycast (screenPos, Vector2.zero);
                if (hit.transform != null) {
                    if (hit.transform.tag == "Monster") {
                        Debug.Log ("Monster" + hit.transform.name);
                        if (hit.transform.name.Contains ("Bat")) {
                            //var id = hit.transform.GetComponent<NetworkIdentity> ().netId;
                            //tTarget = hit.transform.gameObject;
                            var yo = hit.transform.gameObject.GetComponent<NetworkIdentity>().netId;
                            NetworkServer.FindLocalObject (yo).GetComponent<Bat> ().CmdDecreaseHP ();
                        //    CmdYolo ();

                        }

                    }
                }
            }
        }

        }

      
    //[Command]
    //void CmdYolo(){
      
        //var target = tTarget.GetComponent<NetworkIdentity> ().netId;
        //NetworkServer.FindLocalObject (target).GetComponent<Bat> ().CmdDecreaseHP ();
//    }





}

The above code works when I am the Server, but I have no clue how to make it so a Client can do the same thing. I have tried many videos/my best to find this on posts, they mention Commands and netId’s, but I fail to put it together for what I am trying to accomplish.

P.S Don’t mind some of the names of some variables/commands since this is a test project, and when I get stuck I just put random things that pop into my head.

Thanks.

So - your logic only executes for the local player of the pTarget NetworkBehaviour. Assuming the GameObject pTarget is attached to is spawned as a player object you have to send a Command to the server telling it that you’re targetting a particular object (send the object’s NetworkIdentity component as an argument in the Command). The Command should then send an Rpc to all clients instructing them to decrease health or whatever pTarget does.

pTarget is a script attached to my Player. Also what do you mean by the objects NetworkIdentity as an argument? Also the CmdDecreaseHP(), is attached to my Bat(which isn’t probably needed since it’s already on the server, as a Command).

Your targeting Command should send the NetworkIdentity component of the bat to the server so the server knows what bat is being targeted.

Hmm, still not quite sure what you mean, unless its something like CmdTarget(string/int? netID)? sort of thing?I am unfamiliar with sending variables into functions etc, maybe I should start there. Will look into things more, thanks for your help thus far, if you have more input it would be appreciated.

I still don’t get it. When I am on the Server window and click one of the 2 bats, they take damage accordingly and separately. In turn I send a RPC to the clients and update their HP bar visually. So basically I have : When using server - Click Bat - Bat takes damage - Clients see it being damaged. When I click on a client, nothing happens. How do I change my code to work?

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;



public class PClick : NetworkBehaviour {

    // Use this for initialization
    void Start () {
  
    }
  
    // Update is called once per frame
    void Update () {
        if (Input.GetMouseButtonDown (0)) {
            Vector3 mousePos = Input.mousePosition;
            mousePos.z = 10;
            Vector3 screenPos = Camera.main.ScreenToWorldPoint (mousePos);
            RaycastHit2D hit = Physics2D.Raycast (screenPos, Vector2.zero);
            if (hit.transform != null) {

                Debug.Log ("Monster" + hit.transform.name);
                var hi = hit.transform.GetComponent<NetworkIdentity> ().netId;
                CmdRoar (hi);


            }
        }
  
    }



    [Command]
    void CmdRoar(NetworkInstanceId yolo){
      
        NetworkServer.FindLocalObject (yolo).GetComponent<BlahClicked> ().AddOne ();
    }
}

Created a new project to keep things simple, and when I click on the object on the client it changes. So I may be on the right track finally?