This subject prepares me a headache…
My problem:
The player can place bombs wich should be synch other the network, because of time and position and velocity (can be kicked away etc) so they have attached a networkview. All the important decisions should do the server, like damage on objects, players, etc.
I’ll use a ObjectPooler Script for pool the bombs.
public class BombPoolerScript : MonoBehaviour {
public GameObject pooledObject;
public int pooledAmount = 20;
public bool willGrow = true;
public List<GameObject> pooledObjects;
void Start() {
pooledObjects = new List<GameObject>();
for (int i = 0; i < pooledAmount; i++) {
GameObject obj = Instantiate(pooledObject) as GameObject;
obj.SetActive(false);
obj.GetComponent<BombScript>().enabled = true;
pooledObjects.Add(obj);
}
}
public GameObject GetPooledObject() {
for (int i = 0; i < pooledObjects.Count; i++) {
if (!pooledObjects[i].activeInHierarchy) {
return pooledObjects[i];
}
}
if (willGrow) {
GameObject obj = Instantiate(pooledObject) as GameObject;
pooledObjects.Add(obj);
obj.GetComponent<BombScript>().enabled = true;
return obj;
}
return null;
}
}
What is the best way to do this over the network?
my first approach was to always allocate a new networkview id to a bomb…
void Update() {
if (!networkView.isMine) {
return;
}
bool placeBomb = false;
#if UNITY_ANDROID
placeBomb = CustomInput.GetButtonUp("PlaceBomb");
#else
placeBomb = Input.GetButtonUp("PlaceBomb");
#endif
if (Input.GetButtonUp("PlaceBomb") && CanPlaceBomb()) {
GameResults.placedBombs++;
var pos = transform.position;
pos.x = Mathf.Round(pos.x);
pos.z = Mathf.Round(pos.z);
pos.y = 0;
foreach (var poolBomb in bombpooler.pooledObjects) {
if (poolBomb.activeInHierarchy && poolBomb.transform.position == pos) {
return;
}
}
var viewID = Network.AllocateViewID();
networkView.RPC("PlaceBomb", RPCMode.All, pos, viewID);
}
}
[RPC]
void PlaceBomb(Vector3 pos, NetworkViewID viewID) {
var bombObj = bombpooler.GetPooledObject();
bombObj.networkView.viewID = viewID;
var bomb = bombObj.GetComponent<BombScript>();
bomb.time = time;
bomb.range = range;
bombObj.transform.position = pos;
bombObj.SetActive(true);
}
But i run into problems with synch. if I want to find the networkview of the bomb to get the reference to bombscript.
With static ViewId I run into the following problem:
The following state is possible with an static viewID attached to the bomb:
- placed bomb by the Client A explode on the Client A but not on Client B (some ms later)
- bomb is again available in the poolerscript on Client A but not on Client B (some ms later)
- Client A places the same bomb again but on Client B its still active and not exploded…
- the bomb on Client B dont exploded and placed to the new position… (should not happened)
But I need static viewID for finding the bomb… on other objects, because of the reference to the bombscript
I hope I could convey my problem properly