public static object Serialize_ChunkPortal(object _obj, System.Type type, OverloadLevelConvertSerializer serializer) { ChunkPortal obj = (ChunkPortal)_obj; serializer.SerializeX(obj, x => x.Num); serializer.SerializeX(obj, x => x.Chunknum); serializer.SerializeX(obj, x => x.Segnum); serializer.SerializeX(obj, x => x.Sidenum); serializer.SerializeX(obj, x => x.ConnectedChunk); serializer.SerializeX(obj, x => x.ConnectedPortal); serializer.SerializeX(obj, x => x.PortalGeomNum); return(obj); }
//This is called after a level is loaded. Create the GameManager if this is the first level loaded. //This function should do nothing else. public void Awake() { #if !OVERLOAD_LEVEL_EDITOR // Defer the Awake until after user level loading is complete if (UserLevelLoader.IsLoadingUserLevel) { UserLevelLoader.ExecuteAfterLoading(() => { Awake(); }); return; } Debug.Log("LevelData Awake " + Time.realtimeSinceStartup); //If Game Manager doesn't exist (this is the first level to be loaded), create it if (Object.Equals(GameManager.m_gm, null)) //When the game is shutting down in the editor it apparently re-loads the editor level after closing down the GameManager causing this to be called when m_gm is fake-null. So check for real null. { GameManager.Required(m_game_manager_prefab != null, "Game manager prefab not specified"); Instantiate(m_game_manager_prefab, Vector3.zero, Quaternion.identity); } //Check for geometry data GameManager.Required(m_geometry != null, "Geometry data not specified"); //Save the global for the level initializer object GameManager.m_level_data = this; // Add local player immediately. Remote clients will only add players once scene is loaded both on server and locally. if (NetworkManager.IsServer()) { Client.AddPlayer(); } else { GameManager.m_player_ship = PlayerShip.Instantiate(); GameManager.m_local_player = GameManager.m_player_ship.c_player; } GameObject legacy_player_start = GameObject.FindGameObjectWithTag("LegacyPlayerStart"); if (!GameplayManager.IsMultiplayer) { GameManager.m_player_ship.SetSpawnPosAndRotation(legacy_player_start); } if (legacy_player_start != null) { legacy_player_start.SetActive(false); // start has a camera we want to disable } //Get the viewer component GameManager.m_viewer = Camera.main.GetComponent <Viewer>(); GameManager.Required(GameManager.m_viewer != null, "Must have Viewer component on camera"); //Get the mesh containers GameManager.m_mesh_container = GameObject.Find("_container_level_meshes"); // // Do some processing on this object's data. Don't do anything else here. // //Fix up the door references if (m_portal_to_door_references != null) { foreach (var portal_door_ref in m_portal_to_door_references) { int portal_index = portal_door_ref.PortalIndex; if (portal_index >= 0 && portal_index < m_geometry.Portals.Length) { m_geometry.Portals[portal_index].DoorData = portal_door_ref.ReferenceDoor; } else { Debug.LogError(string.Format("Portal Index {0} is out of range for door {1}", portal_index, portal_door_ref.ReferenceDoor.name)); } } } //Create empty level light and reflection probe arrays if they're not present if (m_level_lights == null) { m_level_lights = new SegmentLightInfo[0]; } if (m_level_reflection_probes == null || m_level_reflection_probes.Length == 0) { List <SegmentReflectionProbeInfo> srpi_list = new List <SegmentReflectionProbeInfo>(); // Gather the reflection probes the hard way (slowly) GameObject userContainerObject = GameObject.Find("!rprobes"); if (userContainerObject != null && userContainerObject.transform.parent == null) { // Gather all the reflection probes under "!probes" ReflectionProbe[] rps = userContainerObject.GetComponentsInChildren <ReflectionProbe>(); int count = rps.Length; for (int i = 0; i < count; i++) { SegmentReflectionProbeInfo srpi = new SegmentReflectionProbeInfo(); srpi.ProbeObject = rps[i].gameObject; srpi.SegmentIndex = FindSegmentContainingWorldPosition(rps[i].transform.position); if (srpi.SegmentIndex < 0) { srpi.SegmentIndex = ChunkManager.FindNearestSegment(rps[i].transform.position); } srpi.ProbeType = SegmentReflectionProbeType.UserPlaced; srpi_list.Add(srpi); } } m_level_reflection_probes = srpi_list.ToArray(); if (m_level_reflection_probes == null) { m_level_reflection_probes = new SegmentReflectionProbeInfo[0]; } } NumSegments = m_geometry.Segments.Length; // Associate lights to segments { Dictionary <int, List <SegmentLightInfo> > mapLightsToSegment = new Dictionary <int, List <SegmentLightInfo> >(); foreach (var llight in m_level_lights) { if (llight.SegmentIndex < 0 || llight.SegmentIndex >= NumSegments) { Debug.LogErrorFormat("Level light at invalid segment index {0}", llight.SegmentIndex); continue; } List <SegmentLightInfo> list; if (!mapLightsToSegment.TryGetValue(llight.SegmentIndex, out list)) { list = new List <SegmentLightInfo>(); mapLightsToSegment.Add(llight.SegmentIndex, list); } if (llight.LightObject != null && llight.LightComp != null) { list.Add(llight); } } foreach (var kvp in mapLightsToSegment) { m_geometry.Segments[kvp.Key].Lights = kvp.Value.ToArray(); } // Provide an empty list for the other segments SegmentLightInfo[] dummyList = new SegmentLightInfo[0]; for (int segIndex = 0; segIndex < NumSegments; ++segIndex) { if (mapLightsToSegment.ContainsKey(segIndex)) { continue; } m_geometry.Segments[segIndex].Lights = dummyList; } } // Associate reflection probes to segments { Dictionary <int, List <SegmentReflectionProbeInfo> > mapProbesToSegment = new Dictionary <int, List <SegmentReflectionProbeInfo> >(); foreach (var lprobe in m_level_reflection_probes) { if (lprobe.SegmentIndex < 0 || lprobe.SegmentIndex >= NumSegments) { Debug.LogErrorFormat("Level reflection probe at invalid segment index {0}", lprobe.SegmentIndex); continue; } List <SegmentReflectionProbeInfo> list; if (!mapProbesToSegment.TryGetValue(lprobe.SegmentIndex, out list)) { list = new List <SegmentReflectionProbeInfo>(); mapProbesToSegment.Add(lprobe.SegmentIndex, list); } if (lprobe.ProbeObject != null) { list.Add(lprobe); } } foreach (var kvp in mapProbesToSegment) { m_geometry.Segments[kvp.Key].ReflectionProbes = kvp.Value.ToArray(); } // Provide an empty list for the other segments SegmentReflectionProbeInfo[] dummyList = new SegmentReflectionProbeInfo[0]; for (int segIndex = 0; segIndex < NumSegments; ++segIndex) { if (mapProbesToSegment.ContainsKey(segIndex)) { continue; } m_geometry.Segments[segIndex].ReflectionProbes = dummyList; } } //Find connecting portals for chunk portals foreach (ChunkPortal chunk_portal in m_geometry.ChunkPortals) { if (chunk_portal.ConnectedPortal == -1) { PortalData seg_portal = m_geometry.Portals[m_geometry.Segments[chunk_portal.Segnum].Portals[chunk_portal.Sidenum]]; int connected_segnum = (seg_portal.MasterSegmentIndex == chunk_portal.Segnum) ? seg_portal.SlaveSegmentIndex : seg_portal.MasterSegmentIndex; foreach (int connected_chunk_portal_index in m_geometry.Chunks[chunk_portal.ConnectedChunk].PortalIndices) { ChunkPortal connected_chunk_portal = m_geometry.ChunkPortals[connected_chunk_portal_index]; if (connected_chunk_portal.Segnum == connected_segnum) { chunk_portal.ConnectedPortal = connected_chunk_portal.Num; connected_chunk_portal.ConnectedPortal = chunk_portal.Num; } } Assert.True(chunk_portal.ConnectedPortal != -1); } } //Make list of Chunks CreateChunkList(); //Set up object to access segment visibility if (m_geometry.SegmentToSegmentVisibility == null) { var stopWatch = new System.Diagnostics.Stopwatch(); stopWatch.Start(); Segment2SegmentVis.ComputeSegmentVisibility(m_geometry, 55.0f); stopWatch.Stop(); UnityEngine.Debug.LogFormat("ComputeSegmentVisibility took {0} ms", stopWatch.ElapsedMilliseconds); } if (m_geometry.SegmentToSegmentVisibility != null) { m_segment_visibility = new IndexAs2D(m_geometry.SegmentToSegmentVisibility, NumSegments); } else { m_segment_visibility = null; } //Make a list of ambient sound sources in the level. Might make sense to keep that list here, but the gather function is a little audio-specific if (GameManager.m_audio != null) //Don't do this on game startup { GameManager.m_audio.GatherAmbientSounds(); } //Find the reactor, if one exists Reactor[] reactors = FindObjectsOfType <Reactor>(); if (reactors.Length == 0) { //Debug.Log("There is no reactor in this level!"); Reactor = null; } else { if (reactors.Length > 1) { Debug.Log("There are " + reactors.Length + " reactors in this level! There should be no more than one! Will only use the first one found"); } Reactor = reactors[0]; } // Find the alien warper if one exists. GameObject alien_warp = GameObject.FindGameObjectWithTag("AlienWarp"); if (alien_warp != null) { m_alien_warp_segment = GameManager.m_level_data.FindSegmentContainingWorldPosition(alien_warp.transform.position); Debug.Log("Alien warper is in segment " + m_alien_warp_segment); } else { m_alien_warp_segment = -1; // It's OK if there is no alien warper, most levels don't have one! } //Reset LevelCustomInfo statics in case the level doesn't have a LevelCustomInfo component LevelCustomInfo.Reset(); //Find segments for spawn points SetSpawnPointSegments(m_robot_spawn_points); SetSpawnPointSegments(m_item_spawn_points); SetSpawnPointSegments(m_player_spawn_points); SetSpawnPointSegments(m_mp_camera_points); TriggerWindTunnel.UpdateSegmentsForWindTunnels(); // Deal with Wind Tunnels (WindTunnels) Forcefield.UpdateSegmentsForForcefields(); // Deal with Forcefields // Deal with teleporters. for (int i = 0; i < GameManager.m_level_data.Segments.Length; i++) { GameManager.m_level_data.Segments[i].WarpDestinationSegs = new int[6]; for (int j = 0; j < 6; j++) { GameManager.m_level_data.Segments[i].WarpDestinationSegs[j] = -1; } } //Find & initialize cryotubes InitCryotubes(); // Explode the hierarchy (for optimization reasons) if (CrushHierarchy) { GameManager.m_mesh_container.transform.DetachChildren(); GameObject container = GameObject.Find("_container_level_lava_meshes"); container.transform.DetachChildren(); //container = GameObject.Find("_container_placed_entities"); //int count = container.transform.childCount; //for (int i = count - 1; i >= 0; i--) { // container.transform.GetChild(i).DetachChildren(); //} LevelCustomInfo.TryToCrush(); } Debug.Log("LevelData Awake DONE " + Time.realtimeSinceStartup); #endif // !OVERLOAD_LEVEL_EDITOR }