Clients that aren't master don't always call if(!photonView.IsMine) correctly

Hey guys, sorry for the weirdly worded title, but its whats happening; let me give more detail of whats happening.

So basically, I have a game level where there are 2 players and 1 monster:
- Both the players are able to damage the monster properly.
- The monster is able to damage master client properly
- The monster's initial contact with non master client doesn't register damage (OnCollisionEnter), but my OnCollisionStay function is able to properly damage the non master client.

The monster is created through PhotonNetwork.InstantiateRoomObject.

Here is the monsters code for damaging the player:
private void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.CompareTag("Player"))
        {
            Entity_Multiplayer playerEntity = collision.gameObject.GetComponent<Entity_Multiplayer>();
            playerEntity.TakeDamage(charge_Damage);
            collisionTimer = 0f;
            isCharging = false;
        }
        else if (!collision.gameObject.CompareTag("Enemy") && !collision.gameObject.CompareTag("Projectile")
            && !collision.gameObject.CompareTag("MinionSpawn") && !collision.gameObject.CompareTag("Invisible")
            && !collision.gameObject.CompareTag("Arrow"))
        {
            if (isCharging)
            {
                isCharging = false;
            }
        }
    }

    private void OnCollisionStay(Collision collision)
    {
        if (collision.gameObject.CompareTag("Player"))
        {
            if (collisionTimer >= collisionStayDamageInterval)
            {
                collisionTimer = 0f;
                Entity_Multiplayer playerEntity = collision.gameObject.GetComponent<Entity_Multiplayer>();
                playerEntity.TakeDamage(charge_Damage);
            }
            collisionTimer += Time.deltaTime;
        }
    }

    private void OnCollisionExit(Collision collision)
    {
        if (collision.gameObject.CompareTag("Player"))
        {
            collisionTimer = 0f;
        }
    }

As you can see, the way I apply the damage in OnCollisionStay and OnCollisionEnter are the same, yet only one is properly processed. (I took out all my Debug.Log lines to save clutter)
- The issue isn't the call to
playerEntity.TakeDamage(charge_Damage);
as that is called:

The issue comes inside of the entity script here:
public void TakeDamage(int damage)
    {
        Debug.Log("attempting to take damage");
        if (!photonView.IsMine) return;
        Debug.Log("should take damage, photon view is correct");
    }

I omitted most of the function as its not relevant:
- Always the call:
Debug.Log("attempting to take damage");
is called, but when this function is trigger due to OnCollisionEnter on the non master client, it never gets the call:
Debug.Log("should take damage, photon view is correct");
because it is returned because of the check:
if (!photonView.IsMine) return;
.
- If I remove: if (!photonView.IsMine) return; then both players take damage whenever either is damaged.

I feel like I have overlooked something super simple that is causing this behaviour, but I can't for the life of me figure it out.
Sorry for such a long post, its a very strange outcome. Any help is greatly appreciated!
Thanks,
Connor

Comments

  • Solved it.
    After a bit of debugging (changing which client was master so i could see certain debugs) I realized it wasn't cause by the issue I thought.
    What was happening was there was lag between the position of the monster between the two clients.
    the master client registered that the monster hit the other client, but it hadn't actually hit it yet and therefore that client didnt register it.

    super easy fix, yet not so easy to find....
    If a photon dev sees this... please save people like me this headache and by default in "Photon Transform View" please change it so it runs in the FixedUpdate method, not Update.. this is all that needs to be fixed. I get that its somewhat of a reference class and to use your own IPunObservable, but by default it should be setup right. Even in your own documentation on lag compensation you mention it has to be done in FixedUpdate for proper lag fix, which is the only reason I changed it.