[SOLVED] Client raycast not working

Hey,

Ran into a weird problem while testing out my shooting function in 2D game. Apparently only the servers host has a working raycast + only the host is able to deal damage (because of the working raycast). Meanwhile the clients raycast is all bonkers. Any idea what is causing this?

This is the script handling the shooting.

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

public class Shoot : NetworkBehaviour {

    public int dmg = 1;
    [SerializeField]
    private RaycastHit2D hit;

    GameObject player = GameObject.FindGameObjectWithTag("Player");

    Transform Shootpoint;

    // Use this for initialization
    void Awake () {

        Shootpoint = transform.FindChild("Shootpoint");
        if (Shootpoint == null)
        {
            Debug.Log("No 'shootpoint' set!");
        }
    }
  
    // Update is called once per frame
    void Update ()
    {
        CheckShooting();
    }

    void Shooting()
    {
        //Debug.Log("Testi testi");
        Vector2 ShootPointPos = new Vector2(Shootpoint.position.x, Shootpoint.position.y);
        Vector2 ShootDirection = (Vector2)GameObject.FindGameObjectWithTag("Player").transform.position - ShootPointPos;

        RaycastHit2D hit = Physics2D.Raycast(ShootPointPos, ShootDirection.normalized, -100);
        Debug.DrawLine(ShootPointPos, ShootDirection.normalized * -100);
        Debug.Log(hit.transform.tag);

            if (hit.transform.tag == "Player")
            {
                string uIdentity = hit.transform.name;
                CmdTellServerWhoWasShot(uIdentity, dmg);
            }
    }

    void CheckShooting()
    {
        if (!isLocalPlayer)
        {
            return;
        }

        if (Input.GetKey(KeyCode.A))
        {
            Shooting();
        }
    }

    [Command]
    void CmdTellServerWhoWasShot(string uniqueID, int dmg)
    {
        GameObject go = GameObject.Find(uniqueID);
        go.GetComponent<hp>().lowerHealth(dmg);
    }

  
}

Here is also a gif about the problem (the raycast is swaying under the client, but the hosts raycast is pointing straight to facing direction).

Edit: The gif is recorded on host, but the problem is on client side. The gif is only there to show you the problem.

Make sure the FindGameObjectWithTag(“Player”) is finding the right GameObject. If your client joins when your host is already instantiated you’d have two GameObjects with the ‘Player’ tag.

I’m using another script to give each player unique ID. Is there a way I could use this to give both players the raycasting?

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

public class Player_ID : NetworkBehaviour {

    [SyncVar]
    public string playerUnique;
    private NetworkInstanceId pNetID;
    private Transform ntransform;

    public override void OnStartLocalPlayer()
    {
        GetNetID();
        SetID();
    }

    // Use this for initialization
    void Awake ()
    {
        ntransform = transform;
    }
   
    // Update is called once per frame
    void Update ()
    {
        if(ntransform.name == "" || ntransform.name == "Player(Clone)")
        {
            SetID();
        }
    }

    [Client]
    void GetNetID()
    {
        pNetID = GetComponent<NetworkIdentity>().netId;
        CmdTellServerMyID(MakeUniqueID());
    }

    void SetID()
    {
        if (!isLocalPlayer)
        {
            ntransform.name = playerUnique;
        }
        else
        {
            ntransform.name = MakeUniqueID();
        }
    }

    string MakeUniqueID()
    {
        string uniqueName = "Player" + pNetID.ToString();
        return uniqueName;
    }

    [Command]
    void CmdTellServerMyID(string name)
    {
        playerUnique = name;
    }
}

Both of these players go under the same tag (“Player”).

I think you’re overthinking this. I don’t know what your setup is but if your ‘Shoot’ NetworkBehaviour is attached to the player game object you could use the ‘gameObject’ variable to reference your player’s game object.

I’m not quite sure what you mean (as I’m fairly new with Unity and Unet), but I’m definitely overthinking this problem. I tried a not-so-great solution by simply checking if the player name in the hierarchy was “Player1” or “Player2” and gave both of them separate Void shooting(). This is by no means a great way to do this, but I just wanted to try what would happen. Player2 (client) now has two raycast lines, one working as intended and one broken (the one in the gif I posted before).

if (Input.GetKey(KeyCode.A))
        {
            if(GameObject.Find("Player1"))
            {
                Shooting();
            }
            if (GameObject.Find("Player2"))
            {
                Shooting2();
            }
        }

This is not something I want to do, but at least it did something.

I’m assuming your ‘Shoot’ MonoBehaviour is on the player’s game object.

If so, instead of doing
Vector2 ShootDirection = (Vector2)GameObject.FindGameObjectWithTag(“Player”).transform.position - ShootPointPos;

You could do
Vector2 ShootDirection = (Vector2)transform.position - ShootPointPos;

‘transform’ here indicates the transform of the game object that the script is attached to. This way you should always get the current player’s game object without having to look it up.

1 Like

Thank you Scrorr, that did the trick. I believe at some point I had a similar line of code, but somehow missed the problem itself. Like you said, I was overthinking it!