123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- using UnityEngine;
- namespace Mirror.Examples.CCU
- {
- [AddComponentMenu("")]
- public class CCUNetworkManager : NetworkManager
- {
- [Header("Spawns")]
- public int spawnAmount = 10_000;
- public float interleave = 1;
- public GameObject spawnPrefab;
- // player spawn positions should be spread across the world.
- // not all at one place.
- // but _some_ at the same place.
- // => deterministic random is ideal
- [Range(0, 1)] public float spawnPositionRatio = 0.01f;
- System.Random random = new System.Random(42);
- void SpawnAll()
- {
- // clear previous player spawn positions in case we start twice
- foreach (Transform position in startPositions)
- Destroy(position.gameObject);
- startPositions.Clear();
- // calculate sqrt so we can spawn N * N = Amount
- float sqrt = Mathf.Sqrt(spawnAmount);
- // calculate spawn xz start positions
- // based on spawnAmount * distance
- float offset = -sqrt / 2 * interleave;
- // spawn exactly the amount, not one more.
- int spawned = 0;
- for (int spawnX = 0; spawnX < sqrt; ++spawnX)
- {
- for (int spawnZ = 0; spawnZ < sqrt; ++spawnZ)
- {
- // spawn exactly the amount, not any more
- // (our sqrt method isn't 100% precise)
- if (spawned < spawnAmount)
- {
- // spawn & position
- GameObject go = Instantiate(spawnPrefab);
- float x = offset + spawnX * interleave;
- float z = offset + spawnZ * interleave;
- Vector3 position = new Vector3(x, 0, z);
- go.transform.position = position;
- // spawn
- NetworkServer.Spawn(go);
- ++spawned;
- // add random spawn position for players.
- // don't have them all in the same place.
- if (random.NextDouble() <= spawnPositionRatio)
- {
- GameObject spawnGO = new GameObject("Spawn");
- spawnGO.transform.position = position;
- spawnGO.AddComponent<NetworkStartPosition>();
- }
- }
- }
- }
- }
- // overwrite random spawn position selection:
- // - needs to be deterministic so every CCU test results in the same
- // - needs to be random so not only are the spawn positions spread out
- // randomly, we also have a random amount of players per spawn position
- public override Transform GetStartPosition()
- {
- // first remove any dead transforms
- startPositions.RemoveAll(t => t == null);
- if (startPositions.Count == 0)
- return null;
- // pick a random one
- int index = random.Next(0, startPositions.Count); // DETERMINISTIC
- return startPositions[index];
- }
- public override void OnStartServer()
- {
- base.OnStartServer();
- SpawnAll();
- }
- }
- }
|