- Home /
RTS game. UNet. How to synchronize structs or classes (unit orders)?
Hi! I am trying to make simplest RTS game.
The question is: how to send the orders (classes or structures) to the server from a client and then back to all clients?
As it's known, many of RTS games use so called command (order) based approach. Every unit has it's own "order queue", and we just put any given order for unit to it's order queue and it starts to execute the orders in the queue.
In multiplayer game, I would like to send (synchronize) only the orders for units between server and players (instead of unit positions, health, etc). So a player sends an order to server and then server sends given order to other players and back to sender also. And then units start to execute given order on all clients simultaneously.
In my case an order is a class:
public class Order
{
public int orderType;
public Unit orderUnit;
// etc...
}
Notice please, orderUnit is a Unit class which derives from MonoBehavior and it represents the target unit in order. For example the unit that will be attacked.
Could you give some tips on how to send to the server complex data which include "pointers" to gameObjects which are instances of MonoBehavior class?
Or in general, how to implement this approach? In simple words, how can server say to a client: "Hey! Take unit "A", and give him order "O", and say him to cast a spell to unit "B". How it could be implemented in UNet? Any common or practical tips will be very welcome :)
Thanks a lot.
Answer by AndreasLAN · Sep 14, 2015 at 10:37 AM
I'm making a similar system using UNET and the best way I found so far, is to send the players' input to the server by using [Command] calls and by using [ClientRpc] to broadcast the order from the server to all the clients.
public void AttackFollowClick(Unit target){
if (isServer) {
RpcAttackFollow(target.transform.name);
}
else {
CmdAttackFollow (target.transform.name);
}
}
[ClientRpc]
void RpcAttackFollow(string UnitID){
GameObject target = GameObject.Find (UnitID);
AttackFollowTarget(target);
}
[Command]
void CmdAttackFollow(string UnitID){
GameObject target = GameObject.Find (UnitID);
AttackFollowTarget(target);
RpcAttackFollow(UnitID);
}
You will still have the problem that the orders will arrive at unpredictable intervals at the client side, to compensate for this I also implemented a way to correct the units' positions according to the [SyncVar] unit position at the server end.
Regarding the pointers, you need to synchronise uniqueID's for all units and only send the unitID over the command call. The server then finds the actual game object. I used the gameObject's name to store the uniqueID in this case but it could also be a different dictionary type datastructure connecting the ID's to the game objects on the server side.
Your answer
Follow this Question
Related Questions
how to sync a struct of numbers 0 Answers
RTS enemy tracking using triggers 1 Answer
Networking sync enabled state? 1 Answer
photon variable script does not work :( 2 Answers