Multiplayer- affecting player 2 from player 1

Options
I have spent 4 days on this because I like to experiment before asking for help, as I learn more that way.

I have a player object (P1) that has a laser which it uses to hurt the other player (P2). The Laser object is a linerenderer which is part of a child gameObject of the Player object.

I am using an RPC successfully to show P2's laser on P1's display, so I do seem to understand that part. However, using an RPC to actually damage P2 does not work.

Code to display Laser:
 void ProcessLasers()
    {
            photonView.RPC("ShowLaser1", PhotonTargets.All, Laser.enabled);
    }

[RPC]
    void ShowLaser1(bool setactive)
    {
        if (Laser != null) Laser.enabled = setactive;
    }
This all works.

Now, when I try and hurt P2, I use an RPC again:
Ray ray = new Ray(bulletspawn.transform.position, bulletspawn.transform.forward);

        RaycastHit hit;
        if (Physics.Raycast(ray, out hit, LaserRange))
        {
            if (hit.rigidbody)
            {
                if (hit.rigidbody.gameObject.tag == "Player")
                {
                    photonView.RPC("DoDamage", PhotonTargets.Others, LaserAttackPoints);
                }
            }
        }

 [RPC]
    void DoDamage(int AttackPoints)
    {
        CalculateHit(AttackPoints);
    }


Up to a point, this all works too. The raycast works, the hit is detected and I can set breakpoints and watch the code work and reduce the hitpoints as expected. However this all seems to be working only on P1's 'side'. P2's hit points don't actually change even though they do if you look from P1's point of view. If I use PhotonTargets.All, P1 takes the hits itself, as I would expect.

To clarify, when I step through P1's code, P1 sees P2's hit points reduce, but the 'real' P2 is unaffected. How do I get P2 to actually be affected?

Comments

  • vadim
    Options
    When hit detected, you need to call DoDamage RPC for player hit by laser. But you call RPC for shooter instead. Also RPC with PhotonTargets.Others target skips execution of RPC on local client. Call DoDamage or send RPC to PhotonTargets.All
  • The other player does not know it has been hit.

    I have tried another method, which looks like this:
    if (hit.rigidbody.gameObject.tag == "Player")
                    {
                        Player hitplayer = hit.rigidbody.gameObject.GetComponent("Player") as Player;
                        hitplayer.CalculateHit(LaserAttackPoints);
                    }
    
    This has the same effect, in that I can follow it through and it appears to work, but it only affects the view of P2 that P1 has, and the "real" P2 is unaffected.
  • I am guessing that the reason all this is not working is that the networked version of P2 is not the same as the "real" P2. The "hit" player MUST detect the hit, rather than have the hit detected by the shooter and passed on to the hit player.

    I have tried this approach, but as the laser is part of a child GameObject tagged as "Laser", whose parent is tagged as "Player", the tag of the collider GameObject is always "Player" rather than "Laser", so I can't tell if the two players are colliding, or if one of them is hitting with its laser.
  • vadim
    Options
    vadim wrote:
    When hit detected, you need to call DoDamage RPC for player hit by laser. But you call RPC for shooter instead. Also RPC with PhotonTargets.Others target skips execution of RPC on local client. Call DoDamage or send RPC to PhotonTargets.All
    I meant something like this :
    if (hit.rigidbody.gameObject.tag == "Player")
    {
    	PhotonView hitPLayer = hit.rigidbody.gameObject.GetComponent<PhotonView>();
    	hitPLayer.RPC("DoDamage", PhotonTargets.All, LaserAttackPoints);
    }
    
  • Actually you do need to use PhotonTargets.Others.

    Apart from that you were correct and I thank you for your help.

    Code below for completeness....
    Ray ray = new Ray(bulletspawn.transform.position, bulletspawn.transform.forward);
    
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit, LaserRange))
            {
                
                if (hit.rigidbody)
                {
                    if (hit.rigidbody.gameObject.tag == "Player")
                    {
                        PhotonView hitplayer = hit.rigidbody.gameObject.GetComponent<PhotonView>();
                        hitplayer.RPC("DoDamage", PhotonTargets.Others, LaserAttackPoints);
                    }
                }
            }