Search code examples
unity-game-engineunity3d-unet

Unet Non-Player non-server Health syncing


I have enemy objects spawned by the server. When they get hit, a function on them gets called to apply damage. I can't move or rename this function as it is part of a Unity asset package that has lots of interconnected parts. I can't apply damage from the attacker either for the same reason.

What I have now is that I grab the local player, use them to send a message to the server ([Command]) and the server applies the damage to the enemy on all clients.

This seems like a bad way to do this. Is there a way other than [Command] to send a message to the server to execute a function?

Note: I can't call the [Command] directly from the enemy as its not a player Authority object. Here is the relevant code:

Enemy:

[ClientRpc]
public void RpcTakeDamage(vDamage damage)
{
    base.TakeDamage(damage);
}

override public void TakeDamage(vDamage damage)
{
    if (!isServer)
    {
        vThirdPersonController.instance.GetComponent<NetworkLocalPlayer>().CmdTakeDamage(damage, gameObject.name);
        return;
    }
    RpcTakeDamage(damage);
}

On the player object:

[Command]
public void CmdTakeDamage(vDamage damage, string ai)
{
    GameObject.Find(ai).GetComponent<v_AIController>().TakeDamage(damage);
}

public void damageNetworkEnemy(vDamage damage, GameObject ai)
{
    CmdTakeDamage(damage, ai.name);
}

My question: Is there a better way to do this without finding and going through the player object? A way to message the server without using [Command]?


Solution

  • Commands are the only way for a client to communicate with the server. You could, however, pass the networkinstanceid of that enemy, which would be a much better way of referencing an object. Gameobject.find is very Slow and should alway be avoided. Another improvement would be to give the enemy a reference to his local player after spawn so he doesn’t have to look for him every time he gets hit. Hope that helps a bit.