- Home /
For Loop Freezing Client (May be a Photon-related issue)
I have a for loop to spawn X large asteroids and Y small asteroids, and I use a for loop to spawn until I have reached the limit of asteroids. The code is kind of weird, because I needed the asteroids to be synchronized but without photon views, and so I had to have the master client RPC for asteroids to spawn on everyone's clients. I also have a gameobject called "Offline" with a bool called "OfflineMode" so that when I check it things won't be instantiated with photon. On offline mode nothing freezes, but when it is instantiating things over the network the client freezes and crashes. I can't figure out which part of the for loop is doing it, or whether there are too many RPC calls and that's what's killing my computer. using UnityEngine; using System.Collections; using System.Collections.Generic;
public class SectorManager : MonoBehaviour {
public List <GameObject> LargeAsteroids;
public List <GameObject> SmallAsteroids;
public GameObject MainAsteroid;
public GameObject MiscAsteroid;
public int LargeAsteroidNumber;
public int LargeAsteroidOffset;
public int SmallAsteroidNumber;
public int SmallAsteroidOffset;
public PhotonView ThisPhotonView;
public Manager ManagerScript;
Vector3 RealPosition;
Quaternion RealRotation;
public float SpawnDelay;
public float DesiredTime;
// Use this for initialization
void Start () {
ThisPhotonView = GetComponent<PhotonView> ();
ManagerScript = GameObject.Find ("Manager").GetComponent<Manager> ();
DesiredTime = Time.deltaTime + SpawnDelay;
SetupSector ();
}
// Update is called once per frame
void Update () {
}
public void SetupSector()
{
if (!GameObject.Find ("Offline").GetComponent<OfflineMode> ().Offline)
{
if (!PhotonNetwork.isMasterClient)
{
return;
}
}
for(int A = 0; A < LargeAsteroidNumber; A ++)
{
Vector3 SpawnRotation = new Vector3 (Random.Range (2, 358), Random.Range (2, 358), Random.Range (2, 358));
Vector3 SpawnPos = new Vector3 (Random.Range (transform.position.x - LargeAsteroidOffset, transform.position.x + LargeAsteroidOffset), Random.Range (transform.position.y - LargeAsteroidOffset, transform.position.y + LargeAsteroidOffset), Random.Range (transform.position.z - LargeAsteroidOffset, transform.position.z + LargeAsteroidOffset));
if (!GameObject.Find ("Offline").GetComponent<OfflineMode> ().Offline)
{
ThisPhotonView.RPC ("SpawnLargeAsteroid", PhotonTargets.AllBuffered, SpawnPos, SpawnRotation);
}
else
{
GameObject CurrentAsteroid = (GameObject)Instantiate (MainAsteroid, SpawnPos, Quaternion.Euler (SpawnRotation));
CurrentAsteroid.transform.parent = this.transform;
LargeAsteroids.Add (CurrentAsteroid);
}
}
}
[PunRPC]
public void SpawnLargeAsteroid(Vector3 Position, Vector3 Rotation)
{
GameObject CurrentAsteroid = (GameObject)Instantiate(MainAsteroid, Position, Quaternion.Euler(Rotation));
CurrentAsteroid.transform.parent = this.transform;
LargeAsteroids.Add (CurrentAsteroid);
for (int SA = 0; SA < SmallAsteroids; SA++)
//SA is short for small asteroid.
{
Vector3 SpawnRotation = new Vector3 (Random.Range (2, 358), Random.Range (2, 358), Random.Range (2, 358));
Vector3 SpawnPos = new Vector3 (Random.Range (CurrentAsteroid.transform.position.x - SmallAsteroidOffset, CurrentAsteroid.transform.position.x + SmallAsteroidOffset), Random.Range (CurrentAsteroid.transform.position.y - SmallAsteroidOffset, CurrentAsteroid.transform.position.y + SmallAsteroidOffset), Random.Range (CurrentAsteroid.transform.position.z - SmallAsteroidOffset, CurrentAsteroid.transform.position.z + SmallAsteroidOffset));
ThisPhotonView.RPC ("SpawnSmallAsteroid", PhotonTargets.All, SpawnPos, Quaternion.Euler (SpawnRotation));
}
}
[PunRPC]
public void SpawnSmallAsteroid(Vector3 Position, Vector3 Rotation)
{
GameObject CurrentAsteroid = (GameObject)Instantiate(MiscAsteroid, Position, Quaternion.Euler(Rotation));
SmallAsteroids.Add (CurrentAsteroid);
}
void OnPhotonSerializeView(PhotonStream Stream)
{
if (PhotonNetwork.isMasterClient)
{
foreach (GameObject Asteroid in LargeAsteroids)
{
Stream.SendNext (Asteroid.transform.position);
Stream.SendNext (Asteroid.transform.rotation);
}
foreach (GameObject Asteroid in SmallAsteroids)
{
Stream.SendNext (Asteroid.transform.position);
Stream.SendNext (Asteroid.transform.rotation);
}
}
else
{
foreach (GameObject Asteroid in LargeAsteroids)
{
RealPosition = (Vector3)Stream.ReceiveNext ();
RealRotation = (Quaternion)Stream.ReceiveNext ();
Asteroid.transform.position = Vector3.Slerp (Asteroid.transform.position, RealPosition, 0.1f);
Asteroid.transform.rotation = Quaternion.Slerp (Asteroid.transform.rotation, RealRotation, 0.1f);
}
foreach (GameObject Asteroid in SmallAsteroids)
{
RealPosition = (Vector3)Stream.ReceiveNext ();
RealRotation = (Quaternion)Stream.ReceiveNext ();
Asteroid.transform.position = Vector3.Slerp (Asteroid.transform.position, RealPosition, 0.1f);
Asteroid.transform.rotation = Quaternion.Slerp (Asteroid.transform.rotation, RealRotation, 0.1f);
}
}
}
}
Hi,
I'm currently not sure if you reached any limit of RPC calls but you are calling RPCs from inside other RPCs which might be a bad idea. Currently your $$anonymous$$asterClient calls a RPC to create a large asteroid on all clients and himself. $$anonymous$$ight be okay so far. But inside SpawnLargeAsteroid
any client who executes this function runs through a for-loop and a calls SpawnSmallAsteroid
multiple times via RPC. $$anonymous$$eans that one large asteroid creates I guess too many small asteroids since every client creates additional asteroids.
An approach to solve this is to let the $$anonymous$$asterClient create all spawn positions and their matching rotation data and then send this data bundled to other clients using e.g. RaiseEvent
function.