private static IEnumerator InternalRunClient(QNetGameInitializerData data, Action onDone) { // activate loading screen OnClientLoadingInfoUpdated?.Invoke(true, "LOADING LEVEL", $"Loading {data.LevelName}"); OnClientLoadingStart?.Invoke(); yield return(new WaitForSeconds(0.6f)); // wait some time, lol var sw = Stopwatch.StartNew(); // load world fist LastMapState = QNetMapState.Loading; OnMapStateChanged?.Invoke(QNetMapState.Loading); var isLevelLoading = true; QNetLevelLoader.Load(data.LevelName, () => { isLevelLoading = false; }); while (isLevelLoading) { yield return(new WaitForEndOfFrame()); } OnLevelLoaded?.Invoke(data.LevelName); yield return(new WaitForEndOfFrame()); // update lading screen OnClientLoadingInfoUpdated?.Invoke(true, "LOADING WORLD", "Waiting for server."); GameIsInitializing = false; GameInitialized = true; JEMLogger.Log($"QNetUnity ClientRun main work took {sw.Elapsed.Milliseconds:0.00}ms."); onDone?.Invoke(); }
/// <summary> /// Method run from QNeyHandlerWorldReceiver from message of header WORLD_SERIALIZATION. /// </summary> private static IEnumerator InternalRunLateClientWorldSerializer(Action onDone) { var sw = Stopwatch.StartNew(); // update lading screen OnClientLoadingInfoUpdated?.Invoke(true, "LOADING WORLD", $"DeSerializing {QNetWorldSerializer.SerializedObjectsInMemory} world objects."); // load serialized object in memory var time = DateTime.Now; var isWorldSerializing = true; var worldSerializingLastAction = "not defined"; QNetWorldSerializer.DeSerializeObjectsInMemory(() => { isWorldSerializing = false; }, action => { time = DateTime.Now; worldSerializingLastAction = action; }); while (isWorldSerializing && (DateTime.Now - time).Seconds < DeserializingTimeout) { yield return(new WaitForEndOfFrame()); } if ((DateTime.Now - time).Seconds >= DeserializingTimeout) { ShutdownInitializing(worldSerializingLastAction); yield break; } LastMapState = QNetMapState.Loaded; OnMapStateChanged?.Invoke(QNetMapState.Loaded); // update loading screen OnClientLoadingInfoUpdated?.Invoke(true, "READY", "Setting up player."); GameIsInitializing = false; GameInitialized = true; OnClientLoadingEnd?.Invoke(); // the initialize client OnLoadClientSideContent?.Invoke(); bool isWorldReady = false; OnWorldAndNetworkReady?.Invoke(() => { isWorldReady = true; }); while (!isWorldReady) { yield return(new WaitForEndOfFrame()); } JEMLogger.Log($"QNetUnity ClientLateRun main work took {sw.Elapsed.Milliseconds:0.00}ms."); onDone?.Invoke(); }
private IEnumerator InternalLoadServerLevelOnFly(string levelName) { JEMLogger.Log($"QNetUnity is loading map '{levelName}' on fly."); GameIsDeInitializing = true; GameIsInitializing = true; GameInitialized = false; QNetManager.Server.AcceptNewConnections = false; for (var index = 0; index < QNetPlayer.QNetPlayers.Length; index++) { var p = QNetPlayer.QNetPlayers[index]; p.Loaded = false; } LastMapState = QNetMapState.Unloading; OnMapStateChanged?.Invoke(LastMapState); // destroy players yield return(QNetPlayer.DestroyAllQNetPlayers()); // activate loading screen OnClientLoadingInfoUpdated?.Invoke(true, "UNLOADING WORLD", $"Destroying {QNetWorldSerializer.SerializedAndInstancedObjects.Count} objects."); // destroy world objects var isDestroyingWorldObjects = true; QNetWorldSerializer.DestroySerializedObjects(() => { isDestroyingWorldObjects = false; }); while (isDestroyingWorldObjects) { yield return(new WaitForEndOfFrame()); } // try to destroy rest of QNet objects just for sure if (QNetObjectBehaviour.SpawnedBehaviours.Length != 0) { JEMLogger.Log( $"QNetUnity find and will destroy {QNetObjectBehaviour.SpawnedBehaviours.Length} additional objects that has been created not by QNetWorldSerializer."); } // Destroy all behaviours yield return(QNetObjectBehaviour.DestroyAll()); // clear behaviours just for sure QNetObjectBehaviour.ClearBehaviours(); // activate loading screen OnClientLoadingInfoUpdated?.Invoke(true, "LOADING LEVEL", "Loading level."); LastMapState = QNetMapState.Loading; OnMapStateChanged?.Invoke(LastMapState); var isLevelLoading = true; QNetLevelLoader.Load(levelName, () => { isLevelLoading = false; }); while (isLevelLoading) { yield return(new WaitForEndOfFrame()); } LastMapState = QNetMapState.Loaded; OnMapStateChanged?.Invoke(LastMapState); if (QNetManager.IsServerActive) { // we are on server! // here, we need to send level change info to all clients //var writer = QNetManager.Server.GenerateOutgoingMessage((ushort)QNetUnityLocalHeader.LEVEL_LOAD_ON_FLY); //writer.WriteString(QNetLevelLoader.LevelName); //QNetManager.Server.SendToAll(QNetLocalChannel.DEFAULT, QNetMessageMethod.ReliableOrdered, writer); } GameIsDeInitializing = false; GameIsInitializing = false; GameInitialized = true; QNetManager.Server.AcceptNewConnections = true; JEMLogger.Log($"QNetUnity has loaded map '{levelName}' on fly."); }
private static IEnumerator InternalDeInitialize(Action onDone) { var sw = Stopwatch.StartNew(); // the initialize client OnUnloadClientSideContent?.Invoke(); // activate loading screen OnClientLoadingInfoUpdated?.Invoke(true, "UNLOADING WORLD", "Destroying players."); OnClientLoadingStart?.Invoke(); LastMapState = QNetMapState.Unloading; OnMapStateChanged?.Invoke(LastMapState); // destroy players yield return(QNetPlayer.DestroyAllQNetPlayers()); // activate loading screen OnClientLoadingInfoUpdated?.Invoke(true, "UNLOADING WORLD", $"Destroying {QNetWorldSerializer.SerializedAndInstancedObjects.Count} objects."); // destroy world objects var isDestroyingWorldObjects = true; QNetWorldSerializer.DestroySerializedObjects(() => { isDestroyingWorldObjects = false; }); while (isDestroyingWorldObjects) { yield return(new WaitForEndOfFrame()); } // try to destroy rest of QNet objects just for sure if (QNetObjectBehaviour.SpawnedBehaviours.Length != 0) { JEMLogger.Log( $"QNetUnity find and will destroy {QNetObjectBehaviour.SpawnedBehaviours.Length} additional objects that has been created not by QNetWorldSerializer."); } while (QNetObjectBehaviour.SpawnedBehaviours.Length > 0) { QNetObjectBehaviour.InternalDestroy(QNetObjectBehaviour.SpawnedBehaviours[0]); yield return(new WaitForEndOfFrame()); } // activate loading screen OnClientLoadingInfoUpdated?.Invoke(true, "UNLOADING LEVEL", "Unloading level."); // unload world var isLevelUnLoading = true; QNetLevelLoader.UnLoad(() => { isLevelUnLoading = false; }); while (isLevelUnLoading) { yield return(new WaitForEndOfFrame()); } // clear behaviours just for sure QNetObjectBehaviour.ClearBehaviours(); LastMapState = QNetMapState.NotLoaded; OnMapStateChanged?.Invoke(LastMapState); GameIsDeInitializing = false; GameInitialized = false; OnClientLoadingEnd?.Invoke(); JEMLogger.Log($"QNetUnity DeInitialization main work took {sw.Elapsed.Milliseconds:0.00}ms."); onDone?.Invoke(); }
private static IEnumerator InternalRunHost(QNetConfiguration configuration) { // load world first var targetLevel = ServerNextMapName; // activate loading screen OnClientLoadingInfoUpdated?.Invoke(true, "LOADING LEVEL", $"Loading {targetLevel}"); OnClientLoadingStart?.Invoke(); yield return(new WaitForSeconds(0.6f)); // wait some time, lol var sw = Stopwatch.StartNew(); ServerIsInitializing = true; HostIsInitializing = true; LastMapState = QNetMapState.Loading; OnMapStateChanged?.Invoke(LastMapState); var isLevelLoading = true; QNetLevelLoader.Load(targetLevel, () => { isLevelLoading = false; }); while (isLevelLoading) { yield return(new WaitForEndOfFrame()); } OnLevelLoaded?.Invoke(targetLevel); yield return(new WaitForEndOfFrame()); // TODO: Write objects from save in to memory // TODO: Remove block of code below (DeSerializingObjects) // update lading screen OnClientLoadingInfoUpdated?.Invoke(true, "LOADING WORLD", $"DeSerializing {QNetWorldSerializer.SerializedObjectsInMemory} world objects."); var isWorldSerializing = true; var time = DateTime.Now; var worldSerializingLastAction = "not defined"; QNetWorldSerializer.DeSerializeObjectsInMemory(() => { isWorldSerializing = false; }, action => { time = DateTime.Now; worldSerializingLastAction = action; }); while (isWorldSerializing) { yield return(new WaitForEndOfFrame()); } if ((DateTime.Now - time).Seconds >= DeserializingTimeout) { ShutdownInitializing(worldSerializingLastAction); yield break; } LastMapState = QNetMapState.Loaded; OnMapStateChanged?.Invoke(LastMapState); // update loading screen OnClientLoadingInfoUpdated?.Invoke(true, "READY", "Setting up player."); // then initialize host QNetManager.StartHost(configuration); GameIsInitializing = false; ServerIsInitializing = false; HostIsInitializing = false; GameInitialized = true; OnClientLoadingEnd?.Invoke(); // the initialize client OnLoadClientSideContent?.Invoke(); bool isWorldReady = false; OnWorldAndNetworkReady?.Invoke(() => { isWorldReady = true; }); while (!isWorldReady) { yield return(new WaitForEndOfFrame()); } // we need to call OnNetworkActive event for (var index = 0; index < QNetObjectBehaviour.SpawnedBehaviours.Length; index++) { var obj = QNetObjectBehaviour.SpawnedBehaviours[index]; obj.OnNetworkActive(); } for (var index = 0; index < QNetObjectBehaviour.PredefinedBehaviours.Length; index++) { var obj = QNetObjectBehaviour.PredefinedBehaviours[index]; obj.OnInternalSpawned(); obj.OnNetworkActive(); } JEMLogger.Log($"QNetUnity RunHost main work took {sw.Elapsed.Milliseconds:0.00}ms."); }