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

[UNET] Instantiating bullet hole on all clients?

Discussion in 'Scripting' started by Kovenant, Sep 22, 2017.

  1. Kovenant

    Kovenant

    Joined:
    Sep 18, 2013
    Posts:
    254
    I'm trying to instantiate a bullet hole on all clients in my game using [ClientRpc]. However; MY local player doesn't see the bullet holes eventhou I'm the one shooting, but everyone that is not me sees them.. What am I doing wrong here?

    Edit: The title should be "...on all clients...", but.. well well

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.Networking;
    3.  
    4. public class PlayerShooting : NetworkBehaviour {
    5.  
    6.     [SerializeField] float shotCooldown = .1f;
    7.     [SerializeField] float bulletSpread = .02f;
    8.     [SerializeField] Transform firePosition;
    9.     [Space()]
    10.     [Header("Bullet Hole")]
    11.     [SerializeField] GameObject bulletHolePrefab;
    12.     [SerializeField] float floatInfront = .01f;
    13.     [SerializeField] float bulletHoleLifetime = 45f;
    14.  
    15.     RaycastHit hit;
    16.     float ellapsedTime;
    17.     bool canShoot;
    18.  
    19.     private void Start()
    20.     {
    21.         if (isLocalPlayer)
    22.             canShoot = true;
    23.     }
    24.  
    25.     private void Update()
    26.     {
    27.         if (!canShoot)
    28.             return;
    29.  
    30.             ellapsedTime += Time.deltaTime;
    31.  
    32.         if (Input.GetButton("Fire1") && ellapsedTime > shotCooldown)
    33.         {
    34.             Vector3 spreadDirection = firePosition.forward;
    35.  
    36.             ellapsedTime = 0f;
    37.             CmdFireShot(firePosition.position, spreadDirection + Random.insideUnitSphere * bulletSpread);
    38.         }
    39.     }
    40.  
    41.     [Command]
    42.     void CmdFireShot(Vector3 origin, Vector3 direction)
    43.     {
    44.         Ray ray = new Ray(origin, direction);
    45.         Debug.DrawRay(ray.origin, ray.direction * 3f, Color.red);
    46.  
    47.         bool result = Physics.Raycast(ray, out hit, 150f);
    48.         bool hitEnemy = false;
    49.  
    50.         if(result)
    51.         {
    52.             PlayerHealth enemy = hit.transform.GetComponent<PlayerHealth>();
    53.  
    54.             if(enemy != null)
    55.             {
    56.                 hitEnemy = true;
    57.                 enemy.TakeDamage();
    58.             } else
    59.             {
    60.                 hitEnemy = false;
    61.             }
    62.         }
    63.  
    64.         RpcProcessShotEffects(result, hit.point, hitEnemy);
    65.     }
    66.  
    67.     [ClientRpc]
    68.     void RpcProcessShotEffects(bool result, Vector3 point, bool hitEnemy)
    69.     {
    70.         // Shot Effects: Play();
    71.  
    72.         if(result && !hitEnemy)
    73.         {
    74.             // If the player hits anything else than an enemy, assume we hit the environment
    75.             // and instantiate a bullet hole.
    76.             Quaternion hitRotation = Quaternion.FromToRotation(-Vector3.forward, hit.normal);
    77.             GameObject bHole = Instantiate(bulletHolePrefab, hit.point + (hit.normal * floatInfront), hitRotation) as GameObject;
    78.             Destroy(bHole, bulletHoleLifetime);
    79.         }
    80.     }
    81.  
    82. }
    83.  
     
  2. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    Seems like that should work. Are you sure your lifetime is consistent across clients and it's not just being destroyed quickly?
     
  3. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    “Thread tools>edit title” at the top of the thread :cool:
     
    Kovenant likes this.
  4. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    Is the local player not seeing it the one on the server/host? I don't remember if clientrpcs are called on hosts as if they are clients (the game I'm working on is dedicated server, so I haven't had to deal with this recently). If not then I'd just do the same stuff you're doing in the clientrpc in the command, or more likely split the bulk of the clientrpc out into another method that both the command and clientrpc call, so your instantiation occurs on both the host and all the clients.
     
  5. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    If the host is also a player than they are, yes.
     
  6. Kovenant

    Kovenant

    Joined:
    Sep 18, 2013
    Posts:
    254
    I've managed to fix this... There's nothing wrong with the code.. Eventhou the GameObject is instantiated, it is not instantiated on the network eventhou the code looks like it should run on all clients.. I just needed to add this and it worked:

    Code (CSharp):
    1. NetworkServer.Spawn(bHole);
    ...and done! :)
     
  7. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    That's.....odd. We instantiate effects via Rpc all over the place and it works fine....