简体   繁体   中英

Unity Networking | ClientRpc being called on the wrong player object

The Problem: My RpcDie method is being called on the wrong GameObject.

Ie: When Player A kills Player B, it is Player A who dies - not Player B.

But this is only locally. So the behavior above only happens on Player A's game, and on Player B's game everything seems to be happening as expected. The opposite is also true.

So: Player A kills player B. From Player A's perspective they are dead and Player B is alive. From Player B's perspective, they have died and Player A is alive.


In the Update method of my PlayerHealth script I check to see if the players hp is less than 1. If it is, then I call the CmdDie method:

if (playerHealth < 1)
     CmdDie(); 

From CmdDie I call my RpcDie method:

// Calls RpcDie
[Command]
public void CmdDie ()
{
    RpcDie(); 
}

// Removes the player from the game when killed by another player
[ClientRpc]
void RpcDie ()
{
    // Checks
    if (!isLocalPlayer || PlayerUnit.isDead) return;

    // Toggles + updates     
    StopAllCoroutines(); 
    GameObject.Find("MapManager").GetComponent<GameManager>().playerCount--;
    GetComponent<Renderer>().enabled = false;
    PlayerUnit.isDead = true; 

    // Ragdoll
    ragdoll.SetActive(true); 
    foreach (Transform t in ragdoll.transform) 
       t.transform.position = gameObject.transform.position;
}

From debugging I know that the player's health is being subtracted on the correct GameObject. It is only when a player dies that this 'switching' occurs.

From my assumptions, playerHealth is not stating "who" the player actually is; whether if its Player A or Player B . The script does not know that health should be reduced for Player B , rather than Player A .

Each player would have a PlayerID ; hence, Player A would have PlayerID: 1 , and Player B would have PlayerID: 2 .

A more technical scenario would be the Client to Server communication. When Player A would want to attack Player B , the client (which is Player A ) would send an RPC request to the server that he want to attack Player B .

The server would receive a "Packet" containing the information sent from the RPC , including: PlayerID which is initiating the attack (in this case it is PlayerID: 1 (A)), and the other PlayerID who has been attacked ( PlayerID: 2 ). There would be more information in the packet for instance the WeaponID , and so on.

Lastly, the server would send another RPC to everyone which pseudo code would be something like ReducePlayerHealth(int playerID, int healthAmount, RPC.NotifyAll)

That method would send each and every player in the game a packet in which the client would reduce the health of that specific player. The server must always be in command; therefore, the server sets the data, and the client reads the data.

PS: Had to post it as an answer since I could not input more characters under the comment section of your question.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM