Randomly Generated Voxel level with Photon unity networking

Options
I'm having issues with my game. the first client creates a room, and randomly generates a level made of prefabs. Those prefabs are cubes with materials attached as well as prefabs for spawn spots.

right now I'm using the regular instantiate
[code2=csharp]Instantiate(spawn, (pos + wallheight), Quaternion.identity);
Debug.Log ("new spawn spot created");[/code2]

and my voxels look like

[code2=csharp]cubes[x,y] = (GameObject) Instantiate(prefab, pos, Quaternion.identity);
cubes[x,y].renderer.sharedMaterial = blue;
cubes[x,y].tag = "brick";[/code2]

this of course does not seem to work over the network and the second player gets
[code2=plain]IndexOutOfRangeException: Array index is out of range.
NetworkManager.SpawnMyPlayer () (at Assets/NetworkManager.cs:202)
NetworkManager.OnJoinedRoom () (at Assets/NetworkManager.cs:189)
UnityEngine.GameObject:SendMessage(String, Object, SendMessageOptions)
NetworkingPeer:SendMonoMessage(PhotonNetworkingMessage, Object[]) (at Assets/_IMPORTED/Photon Unity Networking/Plugins/PhotonNetwork/NetworkingPeer.cs:1616)
NetworkingPeer:OnEvent(EventData) (at Assets/_IMPORTED/Photon Unity Networking/Plugins/PhotonNetwork/NetworkingPeer.cs:1466)
ExitGames.Client.Photon.PeerBase:DeserializeMessageAndCallback(Byte[])
ExitGames.Client.Photon.EnetPeer:DispatchIncomingCommands()
ExitGames.Client.Photon.PhotonPeer:DispatchIncomingCommands()
PhotonHandler:Update() (at Assets/_IMPORTED/Photon Unity Networking/Plugins/PhotonNetwork/PhotonHandler.cs:76)[/code2]

where the offending code in network manager looks like
[code2=csharp]void OnJoinedRoom() {
Debug.Log ("OnJoinedRoom");
connecting = false;
SpawnMyPlayer(); //line 189
}

void SpawnMyPlayer() {
AddChatMessage("Spawning player: " + PhotonNetwork.player.name);

spawnSpots = GameObject.FindObjectsOfType<SpawnSpot>();

if(spawnSpots == null) {
Debug.LogError ("WTF?!?!?");
return;
}

SpawnSpot mySpawnSpot = spawnSpots[ Random.Range (0, spawnSpots.Length) ]; //line 202
GameObject myPlayerGO = (GameObject)PhotonNetwork.Instantiate("Playerai", mySpawnSpot.transform.position, mySpawnSpot.transform.rotation, 0);
standbyCamera.SetActive(false);[/code2]
so then I'm thinking about making them photonnetworking.instantiate, but that means hundreds and hundreds of network objects and at least for now I'm intending for them to be static. is it really necessary to give the brick and spawn spot prefabs the photon view component? I did a short test and I had to change the max players count (cant remember if the default is 1000 or 10000 but I went over it easily).

also thinking about childing all those voxels to an empty game object and then just sticking one photon view on that, but I'm not really sure how to go about that right now. any thoughts?

Comments

  • just had a thought. is this a case for RPC? I haven't done that yet either.
  • Tobias
    Options
    You don't need PhotonViews on objects if you can generate all from a seed. Sync the seed and all clients can generate the whole level.
    You also don't need to use a PV to only send the object's data. You can send anything you want! So you could use one PV to sync all you want. Think along the lines of sending: "block x,y, byte[] voxeltype". Where voxeltype can be 0 (empty) or whatever else representing a type, mesh, material, etc.
  • well currently i dont generate them from a seed. that might come much down the road as I'd like a more advanced level generation code but i'd really like to get a basic shell up and running. that would make development a lot easier.

    as for the second part I think i might get what you're saying.
    something like

    [code2=csharp]typeofvoxel[x] byte = // 0 for brick, 1 for spawn, 2 for etc......
    voxelpos[x] Vector3 = //insert vector position here[/code2]

    and then send typeofvoxel and voxelpos over the network and have their client build the level locally? how do i sync arrays like that?
  • Tobias
    Options
    You can send RPCs with arrays as content.
    You should break down the world into chunks and per chunk send only one position (the anchor so to say) and then send only the type or values per voxel (following the anchor).
  • Thanks that was helpful. I was able to set a global variable to my map data on room join in an rpc function

    [code2=csharp]if(master_map == null){ // create it
    }
    buildworld();[/code2]