0

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]?

Lokiare
  • 1,238
  • 1
  • 15
  • 23

1 Answers1

1

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.

Marek Legris
  • 113
  • 1
  • 9
  • Nice, how would I go about getting the networkinstanceid of the enemy, and then using that to find the enemy on the server? – Lokiare May 10 '18 at 09:48
  • Looking back at my code, the vThirdPersonController.instance is a network singleton that has the local network player stored. So that's already in there, but obfuscated. – Lokiare May 10 '18 at 11:10
  • 1
    I found it. You just use 'netID' on the NetworkBehaviour object. Works great! – Lokiare May 10 '18 at 11:27
  • Note that you have to use NetworkServer.FindLocalObject() or ClientScene.FindLocalObject() depending on whether you execute on the server or client. – Marek Legris May 10 '18 at 14:42