using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Networking; /* Traffic controller * Felelős a forgalom irányításáért és a forgalom figyeléséért. * * Az autók innen kérdezik le, hogy adott kereszteződésből merre lehet menni a lámpa szerint, illetve van-e még hely * az adott úton. * * Autókat spawnol (és színez is). * * Lekérdezi a lámpák állapotát. * Jegyzi a várakozó autók számát és elüldi a megfelelő szervernek. * * Csak szerveroldalon fut. */ //Nem kell SyncVar-ral foglalkoznia a UNET-nek [NetworkSettings(channel = 0, sendInterval = 0)] public class TrafficController : NetworkBehaviour { [Header("Network setup")] public string url = "http://127.0.0.1:8080/1"; public string getURI = "/trafficlightStates"; public string putURI = "/roadStates"; [Header("Road setup")] public Road[] roads = new Road[16]; public List crossroadsUnity; private CrossroadPython[] crossroadsPython; [Header("Misc setup")] public GameObject carPrefab; public List carColors; public carCount carCounter; public Color[] colors = { Color.red, Color.yellow, Color.green }; //ezek roadID-k public int[] spawnPosition = { 0, 1, 5, 6, 10, 11, 15, 12 }; public float updateInterval = 1; private float timePassed = 0; private int current = 0; void Start () { if (!isServer) return; StartCoroutine("getState"); } void Update () { if (!isServer) return; timePassed += Time.deltaTime; if (timePassed >= updateInterval) { StartCoroutine("getState"); spawnCar(spawnPosition[current++]); current %= spawnPosition.Length; timePassed = 0; } } IEnumerator getState () { using (WWW www = new WWW(url + getURI)) { yield return www; crossroadsPython = JsonHelper.FromJson(www.text); for(int i = 0; i < 4; i++) { crossroadsUnity[i].colors.RpcUpdateColors( colors[crossroadsPython[i].north], colors[crossroadsPython[i].south], colors[crossroadsPython[i].east], colors[crossroadsPython[i].west] ); } StartCoroutine("putState"); } } IEnumerator putState () { string roadStates = "\"passedCarCount\": " + carCounter.throughput.ToString() + ", \"roadStates\": ["; for (int i = 0; i < 15; i++) roadStates += roads[i].carCount.ToString() + ", "; roadStates += roads[15].carCount.ToString(); roadStates += "]"; byte[] data = System.Text.Encoding.UTF8.GetBytes(roadStates); UnityWebRequest www = UnityWebRequest.Put(url + putURI, data); yield return www.SendWebRequest(); if (www.isNetworkError || www.isHttpError) { Debug.Log(www.error); } } //Beállítja a hívó autó next roadId-jét és megmondja, mehet-e a lámpa alapján. public bool getInfo(int index, string direction, ref int forwardRoadID, ref int rightRoadID) { switch (direction) { case "North": forwardRoadID = crossroadsUnity[index].southNextRoadID; rightRoadID = crossroadsUnity[index].westNextRoadID; return crossroadsPython[index].north == 2; case "South": forwardRoadID = crossroadsUnity[index].northNextRoadID; rightRoadID = crossroadsUnity[index].eastNextRoadID; return crossroadsPython[index].south == 2; case "East": forwardRoadID = crossroadsUnity[index].westNextRoadID; rightRoadID = crossroadsUnity[index].northNextRoadID; return crossroadsPython[index].east == 2; case "West": forwardRoadID = crossroadsUnity[index].eastNextRoadID; rightRoadID = crossroadsUnity[index].southNextRoadID; return crossroadsPython[index].west == 2; default: return false; } } //Megmondja, hogy az autó mehet-e az alapján, hogy hány autó van a cél úton. //Az autó arra megy majd, amerre tud. public bool changeRoad(int current, int next) { if (next == -1) { roads[current].carCount--; return true; } if (roads[next].isThereSpace) { roads[current].carCount--; roads[next].carCount++; roads[next].isThereSpace = false; return true; } else return false; } //Szerveroldalról autót spawnol, ha tud. [Server] public void spawnCar(int index) { if(roads[index].spawnPoint) { if (roads[index].isThereSpace) { roads[index].isThereSpace = false; roads[index].carCount++; GameObject car = (GameObject)Instantiate(carPrefab, roads[index].spawnPoint.transform.position, roads[index].spawnPoint.transform.rotation); car.GetComponent().RoadID = index; car.GetComponent().CarColor = carColors[Random.Range(0, carColors.Count)]; NetworkServer.Spawn(car); } } } } [System.Serializable] public struct CrossroadUnity { public trafficLightColor colors; //int?-et nem támogat unity, invalid érték: -1 //Itt a kereszteződésből kivezető út ID-jét tároljuk. public int northNextRoadID; public int southNextRoadID; public int westNextRoadID; public int eastNextRoadID; } /* Utak kiosztása: * Egy út lehet, hogy fizikailag egy, viszont az alapján van szétosztva, hogy melyik kereszteződésbe torkollik. * Lehet intuitívabb elnevezése lenne road helyett a lane. * * 1 5 * V V * 0 > < 2 4 > < 6 * ^ ^ * 3 7 * * 13 9 * V V * 12 > < 14 8 > < 10 * ^ ^ * 15 11 * * (Észak felfele van [arra mutat a fehér nyíl pályán], a 4 csomópont a 4 kereszteződésnek felel meg.) */ //Unityben egy utat egy ilyen szimbolizál [System.Serializable] public struct Road { //Nem kötelező megadni public Transform spawnPoint; //A safespace állítja public bool isThereSpace; public int carCount; } [System.Serializable] public struct CrossroadPython { public int north; public int south; public int west; public int east; } // https://stackoverflow.com/questions/36239705/serialize-and-deserialize-json-and-json-array-in-unity public static class JsonHelper { public static T[] FromJson (string json) { Wrapper wrapper = JsonUtility.FromJson>(json); return wrapper.Items; } public static string ToJson (T[] array) { Wrapper wrapper = new Wrapper(); wrapper.Items = array; return JsonUtility.ToJson(wrapper); } public static string ToJson (T[] array, bool prettyPrint) { Wrapper wrapper = new Wrapper(); wrapper.Items = array; return JsonUtility.ToJson(wrapper, prettyPrint); } [System.Serializable] private class Wrapper { public T[] Items; } }