Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

When player hits object, tell the server to damage it.

Discussion in 'Multiplayer' started by aaronpaulina, Jul 14, 2015.

  1. aaronpaulina

    aaronpaulina

    Joined:
    Oct 2, 2010
    Posts:
    11
    My brain is fried trying to get my head around the new networking. All I want to do is take the object I hit with a ray, and notify all other clients that the object was destroyed or damaged. please help me before I go crazy? :)



    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEngine.Networking;
    4.  
    5. public class HitInfo
    6. {
    7.     public RaycastHit rayHit;
    8.     public Ray AttackRay;
    9.     public bool didHit;
    10.     public GameObject gameObject;
    11.     public Collider collider;
    12.     public BaseEntity hitEntity;
    13.     public Vector3 hitPoint, hitNormal;
    14.     public float hitDistance;
    15.     public Transform HitTransform;
    16.  
    17. }
    18.  
    19. public class PlayerRaycaster : NetworkBehaviour
    20. {
    21.  
    22.     public GameObject cam;
    23.     private RaycastHit raycastHit;
    24.  
    25.     void Start()
    26.     {
    27.  
    28.     }
    29.  
    30.     void Update()
    31.     {
    32.         if (!isLocalPlayer)
    33.             return;
    34.  
    35.         HitInfo hitInfo = SingleLineTrace(cam.transform.position, 10f);
    36.         if (hitInfo != null)
    37.         {
    38.             //Object hit.
    39.  
    40.         }
    41.     }
    42.  
    43.     private HitInfo SingleLineTrace(Vector3 start, float range)
    44.     {
    45.         if (Physics.Raycast(start, cam.transform.forward, out raycastHit, range))
    46.         {
    47.             if (raycastHit.collider)
    48.             {
    49.                 HitInfo hitinfo = new HitInfo();
    50.                 hitinfo.collider = raycastHit.collider;
    51.                 hitinfo.gameObject = raycastHit.collider.gameObject;
    52.                 hitinfo.hitPoint = raycastHit.point;
    53.                 hitinfo.hitNormal = raycastHit.normal;
    54.                 hitinfo.HitTransform = raycastHit.transform;
    55.                 hitinfo.didHit = true;
    56.                 return hitinfo;
    57.             }
    58.         }
    59.  
    60.         return null;
    61.     }
    62.  
    63.     [Client]
    64.     void TellServerToDestroyObject(GameObject go)
    65.     {
    66.        
    67.         Cmd_DestroyObjectFromServer(go);
    68.     }
    69.  
    70.     [ClientRpc]
    71.     void Rpc_DestroyObjectOnAllClients(GameObject go)
    72.     {
    73.         Destroy(go);
    74.     }
    75.  
    76.     [Command]
    77.     void Cmd_DestroyObjectFromServer(GameObject go)
    78.     {
    79.         Destroy(go);
    80.     }
    81. }
     
  2. Bmandk

    Bmandk

    Joined:
    Aug 18, 2012
    Posts:
    70
    Well, I don't see you calling the Command function. That should just be called when you've detected a hit, and that's pretty much it. So under your if statement:

    Code (CSharp):
    1. if (hitInfo != null)
    2. {
    3.     Cmd_DestroyObjectFromServer(hitInfo.gameObject);
    4. }
     
  3. aaronpaulina

    aaronpaulina

    Joined:
    Oct 2, 2010
    Posts:
    11
    Probably should've mentioned I tried all of those functions on the bottom and it only works if my player is the host.
     
  4. Bmandk

    Bmandk

    Joined:
    Aug 18, 2012
    Posts:
    70
    Well, I just looked up, and as far as I can see, instead of using Destroy(GameObject), you need to use NetworkServer.Destroy(GameObject). Like this:

    Code (CSharp):
    1. [Command]
    2.     void Cmd_DestroyObjectFromServer(GameObject go)
    3.     {
    4.         NetworkServer.Destroy(go);
    5.     }
    There are 3 main things you need to worry about in UNET: NetworkServer, NetworkClient and NetworkManager. Maybe also ClientScene. Loads of information in the scripting reference and manual.
     
  5. aaronpaulina

    aaronpaulina

    Joined:
    Oct 2, 2010
    Posts:
    11
    Still only destroys the object if i'm the host though.
     
  6. Bmandk

    Bmandk

    Joined:
    Aug 18, 2012
    Posts:
    70
    Are the objects you're trying to destroy network spawned? Do they have a NetworkIdentity?

    Or are they just part of the initial scene setup?
     
  7. aaronpaulina

    aaronpaulina

    Joined:
    Oct 2, 2010
    Posts:
    11
    They are all prefabs placed into the scene with NetworkIdentity and NetworkTransforms attached.
     
  8. Bmandk

    Bmandk

    Joined:
    Aug 18, 2012
    Posts:
    70
    Hmm, what about calling the Rpc function to destroy the object?

    Code (CSharp):
    1.     [ClientRpc]
    2.     void Rpc_DestroyObjectOnAllClients(GameObject go)
    3.     {
    4.         Destroy(go);
    5.     }
    6.     [Command]
    7.     void Cmd_DestroyObjectFromServer(GameObject go)
    8.     {
    9.         Rpc_DestroyObjectOnAllClients(go)
    10.     }
     
  9. aaronpaulina

    aaronpaulina

    Joined:
    Oct 2, 2010
    Posts:
    11
    No, doesn't work.. But spawning an object works fine, which I find weird because it's calling a [command] too..

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEngine.Networking;
    4. using UnityEngine.VR;
    5.  
    6. public class HitInfo
    7. {
    8.     public RaycastHit rayHit;
    9.     public Ray AttackRay;
    10.     public bool didHit;
    11.     public GameObject gameObject;
    12.     public Collider collider;
    13.     public BaseEntity hitEntity;
    14.     public Vector3 hitPoint, hitNormal;
    15.     public float hitDistance;
    16.     public Transform HitTransform;
    17.  
    18. }
    19. public class PlayerRaycaster : NetworkBehaviour
    20. {
    21.  
    22.     public GameObject cam;
    23.     private RaycastHit raycastHit;
    24.  
    25.     public GameObject ObjectToSpawn;
    26.  
    27.     void Start()
    28.     {
    29.  
    30.     }
    31.  
    32.     void Update()
    33.     {
    34.         if (isLocalPlayer)
    35.         {
    36.             if (Input.GetButtonDown("Fire1"))
    37.             {
    38.                 //trace for objects
    39.                 HitInfo hitInfo = SingleLineTrace(cam.transform.position, 10f);
    40.  
    41.                 if (hitInfo != null)
    42.                 {
    43.                     //Object hit.
    44.                  
    45.                     Rpc_DestroyObjectOnAllClients(hitInfo.gameObject);
    46.                 }
    47.             }
    48.  
    49.             if (Input.GetButtonDown("Fire2"))
    50.             {
    51.                 //trace for objects
    52.                 HitInfo hitInfo = SingleLineTrace(cam.transform.position, 10f);
    53.  
    54.                 if (hitInfo != null)
    55.                 {
    56.                     //spawn object on server
    57.                    Cmd_SpawnObject(hitInfo.hitPoint,Quaternion.identity);
    58.  
    59.                 }
    60.             }
    61.         }
    62.  
    63.     }
    64.  
    65.     private HitInfo SingleLineTrace(Vector3 start, float range)
    66.     {
    67.         if (Physics.Raycast(start, cam.transform.forward, out raycastHit, range))
    68.         {
    69.             if (raycastHit.collider)
    70.             {
    71.                 HitInfo hitinfo = new HitInfo();
    72.                 hitinfo.collider = raycastHit.collider;
    73.                 hitinfo.gameObject = raycastHit.collider.gameObject;
    74.                 hitinfo.hitPoint = raycastHit.point;
    75.                 hitinfo.hitNormal = raycastHit.normal;
    76.                 hitinfo.HitTransform = raycastHit.transform;
    77.                 hitinfo.didHit = true;
    78.                 return hitinfo;
    79.             }
    80.         }
    81.  
    82.         return null;
    83.     }
    84.  
    85.    
    86.     [Client]
    87.     void TellServerToDestroyObject(GameObject go)
    88.     {
    89.        
    90.         Cmd_DestroyObjectFromServer(go);
    91.     }
    92.  
    93.     [ClientRpc]
    94.     void Rpc_DestroyObjectOnAllClients(GameObject go)
    95.     {
    96.        Cmd_DestroyObjectFromServer(go);
    97.     }
    98.  
    99.     [Command]
    100.     void Cmd_SpawnObject(Vector3 pos,Quaternion rot)
    101.     {
    102.         GameObject g = (GameObject) Instantiate(ObjectToSpawn,
    103.             pos, rot);
    104.  
    105.         NetworkServer.Spawn(g);
    106.     }
    107.  
    108.     [Command]
    109.     void Cmd_DestroyObjectFromServer(GameObject go)
    110.     {
    111.         //Rpc_DestroyObjectOnAllClients(go);
    112.        NetworkServer.Destroy(go);
    113.     }
    114. }
    115.  
     
  10. Bmandk

    Bmandk

    Joined:
    Aug 18, 2012
    Posts:
    70
    Hmm, I'm not quite sure what's going on then.

    My guess would be it's related to the fact that the objects are already in the scene, and not spawned with NetworkServer.Spawn().
     
  11. aaronpaulina

    aaronpaulina

    Joined:
    Oct 2, 2010
    Posts:
    11
    Okay so you can't pass a GameObject through a command apparently, here is the updated code for anyone else having this problem..

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEngine.Networking;
    4. using UnityEngine.VR;
    5.  
    6. public class HitInfo
    7. {
    8.     public RaycastHit rayHit;
    9.     public Ray AttackRay;
    10.     public bool didHit;
    11.     public GameObject gameObject;
    12.     public Collider collider;
    13.     public BaseEntity hitEntity;
    14.     public Vector3 hitPoint, hitNormal;
    15.     public float hitDistance;
    16.     public Transform HitTransform;
    17.  
    18. }
    19. public class PlayerRaycaster : NetworkBehaviour
    20. {
    21.  
    22.     public GameObject cam;
    23.     private RaycastHit raycastHit;
    24.  
    25.     public GameObject ObjectToSpawn;
    26.  
    27.     void Start()
    28.     {
    29.  
    30.     }
    31.  
    32.     private void Update()
    33.     {
    34.         if (!isLocalPlayer)
    35.             return;
    36.  
    37.         if (Input.GetButtonDown("Fire1"))
    38.         {
    39.             //trace for objects
    40.             HitInfo hitInfo = SingleLineTrace(cam.transform.position, 10f);
    41.  
    42.             if (hitInfo != null)
    43.             {
    44.                 //Object hit.
    45.  
    46.                 Cmd_DestroyObjectFromServer(hitInfo.gameObject.GetComponent<NetworkIdentity>().netId);
    47.             }
    48.         }
    49.  
    50.  
    51.         if (Input.GetButtonDown("Fire2"))
    52.         {
    53.             //trace for objects
    54.             HitInfo hitInfo = SingleLineTrace(cam.transform.position, 10f);
    55.  
    56.             if (hitInfo != null)
    57.             {
    58.                 //spawn object on server
    59.                 Cmd_SpawnObject(hitInfo.hitPoint, Quaternion.identity);
    60.             }
    61.         }
    62.     }
    63.  
    64.     private HitInfo SingleLineTrace(Vector3 start, float range)
    65.     {
    66.         if (Physics.Raycast(start, cam.transform.forward, out raycastHit, range))
    67.         {
    68.             if (raycastHit.collider)
    69.             {
    70.                 HitInfo hitinfo = new HitInfo();
    71.                 hitinfo.collider = raycastHit.collider;
    72.                 hitinfo.gameObject = raycastHit.collider.gameObject;
    73.                 hitinfo.hitPoint = raycastHit.point;
    74.                 hitinfo.hitNormal = raycastHit.normal;
    75.                 hitinfo.HitTransform = raycastHit.transform;
    76.                 hitinfo.didHit = true;
    77.                 return hitinfo;
    78.             }
    79.         }
    80.  
    81.         return null;
    82.     }
    83.  
    84.    
    85.     [Client]
    86.     void TellServerToDestroyObject(GameObject go)
    87.     {
    88.         DestroyGO(go);
    89.         NetworkServer.Destroy(go);
    90.         Rpc_DestroyObjectOnAllClients(go);
    91.     }
    92.  
    93.     [ClientRpc]
    94.     void Rpc_DestroyObjectOnAllClients(GameObject go)
    95.     {
    96.         NetworkServer.Destroy(go);
    97.     }
    98.  
    99.     [Command]
    100.     void Cmd_SpawnObject(Vector3 pos,Quaternion rot)
    101.     {
    102.         GameObject g = (GameObject) Instantiate(ObjectToSpawn,
    103.             pos, rot);
    104.  
    105.         NetworkServer.Spawn(g);
    106.     }
    107.  
    108.     [Server]
    109.     void DestroyGO(GameObject go)
    110.     {
    111.         NetworkServer.Destroy(go);
    112.     }
    113.  
    114.  
    115.  
    116.     [Command]
    117.     void Cmd_DestroyObjectFromServer(NetworkInstanceId id)
    118.     {
    119.         GameObject g = NetworkServer.FindLocalObject(id);
    120.         if (g != null)
    121.         {
    122.             NetworkServer.Destroy(g);
    123.         }
    124.     }
    125.    
    126.  
    127. }
    128.  
     
  12. Bmandk

    Bmandk

    Joined:
    Aug 18, 2012
    Posts:
    70
    That's really good to know, thanks for reporting back!