Search Unity

Please help - Followed Unity Networking basics tutorial for my own project but health-bar/bullet hi

Discussion in 'Multiplayer' started by megabrobro, Sep 14, 2017.

  1. megabrobro

    megabrobro

    Joined:
    Jul 8, 2017
    Posts:
    109
    Please help - Followed Unity Networking basics tutorial for my own project but health-bar/bullet hits are only registering on the 'Host' instance of the game.

    I posted a question here: https://gamedev.stackexchange.com/q...player-health-bar-tutorial-only-working-on-se

    I would post it here too, but I think it would just mess the entire thread up, if you cannot click the link and would like to try helping by seeing the code, please let me know and I'll post immediately.

    Kind regards and thanks in advance for reading and helping me.
     
  2. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    How are you determining if this isn't working on the client? Just by watching the health bar? Since the way it is written you won't see the parameter "currentHealth" change on the client unless you set it inside OnChangeHealth, so don't expect it to change. If you want to look at that parameter on the client from the editor add "currentHealth = health;" to OnChangeHealth.

    I'd throw a debug.log message inside TakeDamage right before "currentHealth -= bulletDamage;" to determine if on the server you're actually getting this far. Also put one inside OnChangeHealth to verify the client is calling this method when it is notified of a change to the currentHealth syncvar.
     
    megabrobro likes this.
  3. megabrobro

    megabrobro

    Joined:
    Jul 8, 2017
    Posts:
    109
    Hi there thank you for the help. I am indeed just looking at the healthbar (well also I am looking in the Unity Editor to see each player instance and check the public variable for each there but they remain 100).

    I think perhaps your "currentHealth = health" solution might be what I need. I will go try it now. (I'll also use the debug.logs as you suggest).

    Thanks pal
     
  4. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    Setting "currentHealth = health" on the client there will just help you be able to watch the currentHealth parameter from the editor when the editor acts as a client. After you add that line if currentHealth on the client stays at 100 then I would suspect that the currentHealth parameter on the server isn't being updated either. How a syncvar works is when it is updated on the server, the server sends out an update to all the clients. On the client you're calling a syncvar hook when this happens, which actually happens instead of updating currentHealth itself (that is why you would need to add currentHealth = health in that syncvar hook method to actually set it). Changing the value of a syncvar on the client does NOT send the update back to the server by the way.
     
    megabrobro likes this.
  5. megabrobro

    megabrobro

    Joined:
    Jul 8, 2017
    Posts:
    109
    Sadly this didnt work at all. I've been through the Unity tutorial: - https://unity3d.com/learn/tutorials...rking/networking-player-health?playlist=29690 - many times now and the only difference I can see is that I'm using Ray instead of an actual object with rigidbody, so Im not using OnCollisionEnter but instead using Ray hit.collider.

    The currentHealth = health i think was not working because currentHealth already is health.

    The method OnChangeHealth is the hook for the syncVar currentHealth and should be called and passed the value of currentHealth whenever currentHealth is changed.

    I'm completely stumped, spent several hours in several days trying to figure this out and I'm about to give up :(

    Here is the relevant parts of the code (or at least I think they are relevant):

    from my playercontroller class:

    [Command]
    void CmdFireBullets()
    {
    muzzleFlashObject.SetActive(true);
    audioSource.PlayOneShot(gunFireSound, 0.2f);
    //Create a new bullet
    GameObject newBullet = Instantiate(bulletPrefab, bulletSpawnPoint.transform.position, bulletSpawnPoint.transform.rotation) as GameObject;

    //Spawn the bullet on the clients:
    NetworkServer.Spawn(newBullet);
    }
    from my Bullet class:

    private void CastBulletRay()
    {
    ray = new Ray(bulletSpawnPos, bulletSpawnDirection);
    if (Physics.Raycast(ray, out hit, bulletRayDistance))
    {
    if (hit.collider.tag == "Player")
    {
    Debug.Log("ray has hit a player");
    hit.collider.GetComponent<Player>().TakeDamage(hit.point, bulletDamage);
    Destroy(gameObject);
    }
    if (hit.collider.tag == "Wall")
    {
    Debug.Log("ray has hit a wall");
    Destroy(gameObject);
    }

    }
    }
    }
    from my playerHealth class:
    public const int maxHealth = 100;

    [SyncVar(hook = "OnChangeHealth")]
    public int currentHealth = maxHealth;

    public void TakeDamage(Vector3 hitPoint, int bulletDamage)
    {
    //// check that its Server so that damage only gets applied on the server
    if (!isServer)
    {
    return;
    }

    Debug.Log("taking damage . Current Health is : " + currentHealth);
    audioSource.PlayOneShot(painBodySound);
    currentHealth -= bulletDamage;
    if (currentHealth <= 0)
    {
    currentHealth = 0;
    Debug.Log("Dead!");
    }

    }
    void OnChangeHealth(int health)
    {
    healthBar.sizeDelta = new Vector2(health, healthBar.sizeDelta.y);
    Debug.Log("healthbar and currenthealth changed for player");
    }




    I know that it is only getting called on the server/host. Because if I make the Editor version host , I see the debug logs pop up and the healthbar works, the variable changes as expected and the sound is played. But on the client it isnt.

    Again, I have the part: if (!isServer) return; in the top of the method for TakeDamage as instructed by the Unity tutorial .


    Any help would be massively appreciated. As i say I've tried everything and im about to give up sadly.​
     
  6. megabrobro

    megabrobro

    Joined:
    Jul 8, 2017
    Posts:
    109

    Hi again, I was already typing my above msg before I read this. Thanks again for replying.

    According to the tutorial i linked to, if I change the value of the SyncVar currentHealth on the server, then it will call OnChangeHealth which is the hook for the SyncVar, and inside that hook method i have written code to change the health on the actual client.

    Could you be kind enough to check my code i paste above to see if what im saying is correct?


    Thanks again
     
  7. megabrobro

    megabrobro

    Joined:
    Jul 8, 2017
    Posts:
    109
    I can actually see the problem i think, but have no clue how to fix it. My code appears the exact same as the Unity tutorial.

    But OnChangeHealth will be called on all clients whenever currentHealth is changed. This is fine but each player has its own currentHealth value (obviously). Now my TakeDamage method just returns if the collider that was hit (where the TakeDamage method is being triggered from) is NOT the server.

    I need to somehow take the collision of the ray, and update that characters health value (but ONLY on the server), then that OnChangeHealth method should have logic to update all clients with their correct corresponding currentHealth values stored on the server??? Is that correct? Im so stuck :S
     
  8. megabrobro

    megabrobro

    Joined:
    Jul 8, 2017
    Posts:
    109
    I think I just need to change the currentHealth syncVar on the server. Which is happening when the server is the player taking the shots (ie. The other player is taking damage and healthbar changing). But if it isnt the server player taking the shot, the health isnt changing.
     
  9. Xype

    Xype

    Joined:
    Apr 10, 2017
    Posts:
    339
    Each player needs to have a syncvar health that is not public, so that it is local to the object it is attached to, then use a get; set; to update it. That way its not trying to update a public variable.
     
    megabrobro likes this.
  10. megabrobro

    megabrobro

    Joined:
    Jul 8, 2017
    Posts:
    109
    Ahhhh!!! Nice thanks you Xype!!! I thought I'd tried everything was about to give up on the whole project because I couldnt see any difference between mine and the tutorials.

    I can get back to work on this later and hopefully move the project on massively now. Thank you so much
     
  11. megabrobro

    megabrobro

    Joined:
    Jul 8, 2017
    Posts:
    109

    Interestingly, (i'm about to go try it, but thought I'd re-check the tutorial here: https://unity3d.com/learn/tutorials...rking/networking-player-health?playlist=29690

    The tutorial has a public SyncVar ?!?

    Nevertheless this does sound like it will be my solution and I will report back here to confirm either way. thanks again
     
  12. megabrobro

    megabrobro

    Joined:
    Jul 8, 2017
    Posts:
    109

    Sadly this made no difference. The problem is still the exact same. My debug.log tells me the ray hits the player (when fired by either host or clients), but the Sound Effect, health reduction, and healthbar updating only happen inside the host instance when the host fires bullets.

    I'm so lost now, I am about to just upload the whole project in the hope that somebody can run it inside their Unity and see what my issue is. Really sad as I was making massive strides towards my gaame until this problem has taken my over 2 weeks and I still can't overcome it.

    The link to the complete project files will appear here in a few minutes.

    Thanks for all the help so far guys, unfortunately Im still back where I started.



    HERE IS THE LINK TO MY CURRENTLY FAILED PROJECT. THIS IS THE COMPLETE PROJECT AND SHOULD OPEN IN ANOTHER UNITY (ps. I have no idea why it is over 300mb): http://myaccount.dropsend.com/file/da25f2b5db5f69c6
     
    Last edited: Sep 16, 2017