Ejemplo n.º 1
0
    // 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;
                }
            }
        }
    }
Ejemplo n.º 2
0
    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);
            }
        }
    }