// Update is called once per frame void Update() { lock (state) { if (changeSceneOperation != null) { if (changeSceneOperation.isDone) { changeSceneOperation = null; } } if (changeSceneOperation == null) { if (currentScene != state.scenekey) { if (currentScene != null) { changeSceneOperation = SceneManager.UnloadSceneAsync(currentScene); changeSceneOperation.completed += (operation) => { currentScene = null; }; } else { if (state.scenekey != null) { var scene = state.scenekey; changeSceneOperation = SceneManager.LoadSceneAsync(scene, LoadSceneMode.Additive); changeSceneOperation.completed += (operation) => { currentScene = scene; }; } } } } if (currentAgentPrefabKey != state.carkey) { foreach (var item in avatars) { Destroy(item); } avatars.Clear(); currentAgentPrefabKey = state.carkey; } if (currentAgentPrefabKey != null) { while (avatars.Count > state.agents.Count) { var go = avatars.Last(); avatars.Remove(go); Destroy(go); } while (avatars.Count < state.agents.Count) { var go = GameObject.Instantiate(manager.Car(currentAgentPrefabKey), transform); avatars.Add(go); foreach (var item in go.GetComponentsInChildren <ProfileController>()) { DestroyImmediate(item); } foreach (var item in go.GetComponentsInChildren <Vehicle>()) { DestroyImmediate(item); } foreach (var item in go.GetComponentsInChildren <Wheel>()) { DestroyImmediate(item); } foreach (var item in go.GetComponentsInChildren <Rigidbody>()) { DestroyImmediate(item); } foreach (var item in go.GetComponentsInChildren <Collider>()) { DestroyImmediate(item); } foreach (var item in go.GetComponentsInChildren <Autopilot>()) { DestroyImmediate(item); } // and anything else to turn this into a husk... } for (int i = 0; i < state.agents.Count; i++) { avatars[i].transform.position = state.agents[i].position; avatars[i].transform.rotation = state.agents[i].rotation; } } } }
public IEnumerator TrainingWorkerCoroutine() { while (true) { TrainingRequest request; while (!trainingManager.requests.TryDequeue(out request)) { yield return(null); } // dereference to the actual objects that will be passed around var path = trainingManager.Circuit(request.circuit); var prefab = trainingManager.Car(request.car); // load the scene and create the agent trainer var asyncoperation = SceneManager.LoadSceneAsync(path, LoadSceneMode.Additive); while (!asyncoperation.isDone) { yield return(null); } var scene = SceneManager.GetSceneByName(path); var root = scene.GetRootGameObjects().Select(x => x.GetComponentInChildren <Track>()).Where(x => x != null).First(); // set up interpolated paths. this should be done before the manager is added. var geometry = root.GetComponentInChildren <TrackGeometry>(); // delete existing interpolations var existing = geometry.GetComponentsInChildren <InterpolatedPath>(); foreach (var item in existing) { DestroyImmediate(item); // delete immediately as the manager should search for paths in its Start() method. } // and cars var cars = geometry.transform.Find("Cars"); if (cars) { Destroy(cars.gameObject); } foreach (var item in interpolationCoefficients) { var interpolated = geometry.gameObject.AddComponent <InterpolatedPath>(); interpolated.coefficient = item; interpolated.Initialise(); } // we add the manager right away. we don't need to worry about removing the old one, because the scene will be unloaded at the end of this IAgentManager manager = null; if (request.agent == "profile") { manager = root.gameObject.AddComponent <ProfileAgentManager>(); } if (request.agent == "path") { manager = root.gameObject.AddComponent <PathAgentManager>(); } manager.SetAgentPrefab(prefab); var training = true; var running = true; // setup the callbacks manager.OnComplete.RemoveAllListeners(); manager.OnComplete.AddListener((x) => { Debug.Log("TrainingRequest Complete"); OnTrainingRequestComplete?.Invoke(manager); request.circuit = ""; request.car = ""; OnTrainingFrame?.Invoke(request, manager); training = false; SceneManager.UnloadSceneAsync(path).completed += (asyncresult) => { running = false; }; }); // and let it go... while (running) { if (training) { OnTrainingFrame?.Invoke(request, manager); } yield return(null); } } }