I am making a simple network program, and I aim to learn about server and client commands with a more direct approach of designing C# codes in a way where a script can handle both the server and the client actions (commands, functions, methods, etc.). I learned a few things from this documentation article here. So far, I understood how the client->server works, and how I should be designing my C# code. I may not be as clear on server->client, though.
I still haven’t figure out how client->server->client and server->client->server works.
The picture shown above is a very simple project. I click on the cube, and it will turn red. I release the mouse button, and it will turn white. Here’s the NetworkBehaviour codes for the Input Manager game object, which handles setting the cube to the color red or white when clicking on the cube. The Input Manager game object is placed on the same level as the Main Camera. The Cube is a prefab with a NetworkIdentity attached to it, and has been registered.

using UnityEngine;
using UnityEngine.Networking;
using System.Collections;
using System.Collections.Generic;
public class InputManager : NetworkBehaviour {
public List<GameObject> selectedObjects;
protected void Start() {
this.selectedObjects = new List<GameObject>();
}
protected void Update() {
if (Input.GetMouseButtonDown(0)) {
SelectOrder();
}
else if (Input.GetMouseButtonUp(0)) {
CmdClearColor();
RpcClearColor();
this.selectedObjects.Clear();
}
CmdMoveOrder();
RpcMoveOrder();
}
public void SelectOrder() {
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit)) {
this.selectedObjects.Add(hit.collider.gameObject);
}
}
[Command]
public void CmdMoveOrder() {
for (int i = 0; i < this.selectedObjects.Count; i++) {
ServerMoveOrder(this.selectedObjects[i]);
}
}
[ClientRpc]
public void RpcMoveOrder() {
for (int i = 0; i < this.selectedObjects.Count; i++) {
Renderer renderer = this.selectedObjects[i].GetComponent<Renderer>();
if (renderer != null) {
renderer.material.color = Color.red;
}
}
}
[Command]
public void CmdClearColor() {
for (int i = 0; i < this.selectedObjects.Count; i++) {
ClearColor(this.selectedObjects[i]);
}
}
[ClientRpc]
public void RpcClearColor() {
for (int i = 0; i < this.selectedObjects.Count; i++) {
Renderer renderer = this.selectedObjects[i].GetComponent<Renderer>();
if (renderer != null) {
renderer.material.color = Color.white;
}
}
}
[ClientCallback]
public void ServerMoveOrder(GameObject obj) {
Renderer renderer = obj.GetComponent<Renderer>();
if (renderer != null) {
renderer.material.color = Color.red;
}
}
[ClientCallback]
public void ClearColor(GameObject obj) {
Renderer renderer = obj.GetComponent<Renderer>();
if (renderer != null) {
renderer.material.color = Color.white;
}
}
}
The code stops working on the client side, in the Update() code. I believed that [ClientRpc] and [Command] can be called one after another in the Update(), it’s just that I am not sure how to design the C# code to make it happen.
Could someone tell me what I need to do? And how to design the C# code to make client->server->client and server->client->server work?
Thanks in advance.

