Confused about what should be used RPC's and what should be used to be serialized

Options
Hi everyone.

I'm having this problem: a player attacks other player and everything works fine - the health is decremented and the healthbar changes (in this case it's a cube that changes his color). But if other player joins the room after that happening, the player that was attacked has full health and his healthbar hasnt changed and the RPC is being sent to AllBuffered.

I thought that if the RPC is sent to AllBuffered that method (like TakeDamage() that decrements health) is used for the players that join the room later but that isnt happening, is that normal? Should serialize the health value and the color of the healthbar in the OnPhotonSerializeView() ?

Heres the part of my code that does that:

private void Attack(int damage) { // Check if some player was hit int playerAttackedID = getPlayerAttackedID(); if(playerAttackedID > 0) { Debug.Log("Player " + playerAttackedID + " was attacked"); GameObject[] players = GameObject.FindGameObjectsWithTag("Player"); foreach(GameObject player in players) { PhotonView playerPhotonView = player.GetComponent<PhotonView>(); if(player == null) { Debug.Log("Player GameObject not found!"); } if(player.GetPhotonView() != null) { Debug.Log(player); if(player.GetPhotonView().ownerId == playerAttackedID) { player.GetComponent<PhotonView>().RPC("TakeDamage", PhotonTargets.AllBuffered, damage); } } } } else { Debug.Log("No one was hit"); } } [RPC] public void TakeDamage(int damage) { health = health - damage; Debug.Log("Health: " + health + "%"); AffectHealth(); if(health <= 0) { DestroyObject(gameObject); } } // Changes the HealthCube Color private void AffectHealth() { if(healthCube == null) { Debug.Log("deu null"); } else { Vector3 lifeColor = LifeColor(health); healthCube.renderer.material.color = new Color(lifeColor.x/255.0f, lifeColor.y/255.0f, lifeColor.z, 1f); } } void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info) { if(stream.isWriting) { stream.SendNext(rigidbody.position); stream.SendNext(rigidbody.velocity); } else { Vector3 syncPosition = (Vector3)stream.ReceiveNext(); Vector3 syncVelocity = (Vector3)stream.ReceiveNext(); syncTime = 0f; syncDelay = Time.time - lastSynchronizationTime; lastSynchronizationTime = Time.time; syncEndPosition = syncPosition + syncVelocity * syncDelay; syncStartPosition = rigidbody.position; } }

Comments

  • vadim
    Options
    Both approached should work. But OnPhotonSerializeView is preferable because it does not keep unnecessary outdated health updates on server and does not spam new clients with old RPC's (only last is useful in fact).
    You should not use DestroyObject() for PhotonView objects. Call PhotonNetwork.Destroy() once on owner only.