What it the right way to execute functions on the server and clients as well?

[ClientRpc] is only clients.
I need something that will cause the function to run on the server and all of the clients. is there anything like that?

What I’m doing right now is:

[ClientRpc]
    void Rpc_func()
    {
        func();
    }

    void func()
    {
        //
    }

And calling both when I need to.

[Command]
private void CmdComand()
{
   RpcToClients()
}

[ClientRpc]
private void RpcToClients()
{
   Whatever you want it to do.
}

Im using something like that, I don’t really like how it looks like but it works so :smile:

Chom1czek, your example does not solve the task of running a same function on server and client because the code within the ClientRpc is executed on all clients, but not on the server. If you want the code to be run on the server, it will work on hosts only, where you have both server and client in one instance, but it won’t run the code on dedicated servers.

Sahkan, I think your intial approach of using another function call is quite fine. One could just call the function either from server-side (e.g. from a command) or client-side (e.g. from an Rpc). You could even pass a boolean flag like firedOnClient or something. I actually think yours is a clean and structured solution already. Currently, I don’t know other UNET mechanics to achieve this yet, or why there even would be a need to have such. But maybe there are some reasons or use cases.

Honestly, the way to approach something is entirely dependant on what exactly it is you’re trying to do. Maybe it’s something that has use call backs. Maybe it’s something that can be done via an animation event. However, @Chom1czek 's approach does PARTIALLY solve the task…possibly…

[Command]
private void CmdComand()
{
   RpcToClients();
   //CODE GOES HERE TO EXECUTE THE PROCESS ON THE SERVER.
}
[ClientRpc]
private void RpcToClients()
{
   //CODE GOES HERE TO EXECUTE THE PROCESS ON ALL CLIENTS
}

Well I think I even seen some guy from Unity that said it’s legit but if you got better ideas I like to check it out :slight_smile:

Can I ask a backup question along these lines? I’ve been trying to sync animations for awhile now, and the “Network Animator” script is not working as I thought it would. My unit’s animations sync properly with the Network Animator if I uncheck “Local Player Authority” on my Network Identity script for the object. However, I need my objects to have Local Player Authority in order for them to be spawned and registered with different remote clients. The animations do NOT sync when Local Player Authority is checked, only when it is unchecked – I don’t know why this is.

So using what you guys are discussing, I get the fact that a client needs to call a [Command] to execute a function on the server. However, where does the [ClientRpc] function need to sit? Should it be in a script only located on a server object? Or can it be called from the same object/script as the one that makes the [Command] function call?

http://docs.unity3d.com/Manual/UNetActions.html

@Velo222 I’ll expand on my example/suggestion a bit more.

public class PlayerInput : NetworkBehaviour
{

     public Material thisMaterial;

     void Update()
     {
          if(Input.GetKey(Keycode.SPACE))
               CmdChangeColor(); //This sends a request to the server to execute the "CmdChangeColor" function on the server.
     }

     public void ChangeColor()
     {
          thisMaterial.color = new Color(255, 255, 255,255);
     }

     [Command]
     public void CmdChangeColor()
     {
          RpcClientChangeColor(); //This sends a message from the server to all connected clients that have THIS GameObject and tells them to execute all code inside the "RpcClientChangeColor" function.

          ChangeColor(); //This executes the "ChangeColor" function on the server ONLY.
     }

     [ClientRpc]
     public void RpcClientChangeColor()
     {
          ChangeColor(); //This executes the "ChangeColor" function on the client ONLY.
     }
}

All this code exists in a single script on the Player GameObject. When the player presses the SPACE BAR the Command portion is executed on the SERVER, which in turn sends a message to all connected clients to execute the ClientRpc portion.

1 Like

Okay thank you. I’m getting a clearer picture. :slight_smile:

Thanks for everyone who tried to help. I guess I will stick with my method for now.

What do you mean everyone who tried to help? I gave you the answer in my first post.

I realize this post is very old, but I had this problem too and wanted to contribute. Isn’t the server also considered a client?

I just use SyncVar hooks if it’s something like changing a color. This way all you have to do is call the function on the server, and it will also do the same thing on all clients. Plus it’s buffered so it works on future clients, very simple!

[SyncVar(hook="SetColor")]
public Color32 MyColor;

public override void OnStartClient()
{
    SetColor(MyColor);
}

public void SetColor(Color32 color)
{
    MyColor = color;
    GetComponent<MeshRenderer>().material.color = MyColor;
}

I wouldn’t normally write nonsense like this, but if you run DoSomething() the method something() will be called on the server and all clients no matter who is calling it, as long as if a client it has the proper authority over the object to issue commands.

public void DoSomething()
{
    if (isServer)
    {
        something();
        RpcDoSomething();
    }
    else
    {
        CmdDoSomething();
    }
}

[ClientRpc]
void RpcDoSomething()
{
    something();
}

[Command]
void CmdDoSomething()
{
    something();
    RpcDoSomething();
}

private void something()
{
    Debug.Log("something is done");
}
1 Like

I’m testing with the example of incrementing a value one unit every time. If the server calls the function, the value is incremented twice.