306 lines
8 KiB
C#
306 lines
8 KiB
C#
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://localhost:8080/";
|
|
public string getURI = "/trafficLights/";
|
|
public string putRoadsURI = "/roads/";
|
|
public string putCarCountURI = "/passedCarCount";
|
|
|
|
[Header("Road setup")]
|
|
public Road[] roads = new Road[16];
|
|
public List<CrossroadUnity> crossroadsUnity;
|
|
public TrafficLights trafficLights;
|
|
|
|
[Header("Misc setup")]
|
|
public GameObject carPrefab;
|
|
public List<Color> carColors;
|
|
public carCount carCounter;
|
|
//ezek roadID-k
|
|
public int[] spawnPosition = { 0, 1, 5, 6, 10, 11, 15, 12 };
|
|
public float updateInterval = 1;
|
|
public float spawnInterval = 0.5f;
|
|
|
|
private float timePassedUpdate = 0;
|
|
private float timePassedSpawn = 0;
|
|
private int current = 0;
|
|
|
|
void Start () {
|
|
if (!isServer) return;
|
|
|
|
trafficLights = new TrafficLights();
|
|
|
|
StartCoroutine("getState");
|
|
}
|
|
|
|
void Update () {
|
|
if (!isServer) return;
|
|
|
|
timePassedUpdate += Time.deltaTime;
|
|
if (timePassedUpdate >= updateInterval)
|
|
{
|
|
StartCoroutine("getState");
|
|
StartCoroutine("putRoads");
|
|
StartCoroutine("putCarCount");
|
|
|
|
timePassedUpdate = 0;
|
|
}
|
|
|
|
timePassedSpawn += Time.deltaTime;
|
|
if (timePassedSpawn >= spawnInterval)
|
|
{
|
|
spawnCar(spawnPosition[current++]);
|
|
current %= spawnPosition.Length;
|
|
timePassedSpawn = 0;
|
|
}
|
|
}
|
|
|
|
|
|
IEnumerator getState ()
|
|
{
|
|
using (WWW www = new WWW(url + getURI))
|
|
{
|
|
yield return www;
|
|
|
|
trafficLights.roadSystem = JsonUtility.FromJson<RoadSystem>(www.text);
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
crossroadsUnity[i].colors.RpcUpdateColors(trafficLights[i].N, trafficLights[i].E, trafficLights[i].S, trafficLights[i].W);
|
|
|
|
trafficLights.isWithoutLights[i] = !(trafficLights[i].N != "off" && trafficLights[i].E != "off" && trafficLights[i].S != "off" && trafficLights[i].W != "off");
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
IEnumerator putRoads ()
|
|
{
|
|
string roadStates = "{ \"NW\": { \"W\":" + roads[0].carCount.ToString() +
|
|
",\"N\":" + roads[1].carCount.ToString() +
|
|
",\"E\":" + roads[2].carCount.ToString() +
|
|
",\"S\":" + roads[3].carCount.ToString() +
|
|
"}" +
|
|
", \"NE\": { \"W\":" + roads[4].carCount.ToString() +
|
|
",\"N\":" + roads[5].carCount.ToString() +
|
|
",\"E\":" + roads[6].carCount.ToString() +
|
|
",\"S\":" + roads[7].carCount.ToString() +
|
|
"}" +
|
|
", \"SE\": { \"W\":" + roads[8].carCount.ToString() +
|
|
",\"N\":" + roads[9].carCount.ToString() +
|
|
",\"E\":" + roads[10].carCount.ToString() +
|
|
",\"S\":" + roads[11].carCount.ToString() +
|
|
"}" +
|
|
", \"SW\": { \"W\":" + roads[12].carCount.ToString() +
|
|
",\"N\":" + roads[13].carCount.ToString() +
|
|
",\"E\":" + roads[14].carCount.ToString() +
|
|
",\"S\":" + roads[15].carCount.ToString() +
|
|
"}" +
|
|
"}";
|
|
|
|
|
|
byte[] data = System.Text.Encoding.UTF8.GetBytes(roadStates);
|
|
UnityWebRequest www = UnityWebRequest.Put(url + putRoadsURI, data);
|
|
yield return www.SendWebRequest();
|
|
|
|
if (www.isNetworkError || www.isHttpError)
|
|
{
|
|
Debug.Log(www.error);
|
|
}
|
|
}
|
|
|
|
IEnumerator putCarCount ()
|
|
{
|
|
byte[] data = System.Text.Encoding.UTF8.GetBytes(carCounter.throughput.ToString());
|
|
UnityWebRequest www = UnityWebRequest.Put(url + putCarCountURI, 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)
|
|
{
|
|
bool canGo = trafficLights.canGo(index);
|
|
switch (direction)
|
|
{
|
|
case "North":
|
|
forwardRoadID = crossroadsUnity[index].southNextRoadID;
|
|
rightRoadID = crossroadsUnity[index].westNextRoadID;
|
|
return trafficLights[index].N == "green" || canGo;
|
|
case "East":
|
|
forwardRoadID = crossroadsUnity[index].westNextRoadID;
|
|
rightRoadID = crossroadsUnity[index].northNextRoadID;
|
|
return trafficLights[index].E == "green" || canGo;
|
|
case "South":
|
|
forwardRoadID = crossroadsUnity[index].northNextRoadID;
|
|
rightRoadID = crossroadsUnity[index].eastNextRoadID;
|
|
return trafficLights[index].S == "green" || canGo;
|
|
case "West":
|
|
forwardRoadID = crossroadsUnity[index].eastNextRoadID;
|
|
rightRoadID = crossroadsUnity[index].southNextRoadID;
|
|
return trafficLights[index].W == "green" || canGo;
|
|
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<CarHL>().RoadID = index;
|
|
car.GetComponent<CarHL>().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 Crossroads
|
|
{
|
|
public string N;
|
|
public string E;
|
|
public string S;
|
|
public string W;
|
|
}
|
|
|
|
[System.Serializable]
|
|
public struct RoadSystem
|
|
{
|
|
public Crossroads NW;
|
|
public Crossroads NE;
|
|
public Crossroads SE;
|
|
public Crossroads SW;
|
|
}
|
|
|
|
public class TrafficLights
|
|
{
|
|
public RoadSystem roadSystem;
|
|
|
|
public bool[] isWithoutLights = { true, true, true, true };
|
|
public bool[] isThereSpace = { true, true, true, true };
|
|
|
|
public bool canGo(int i)
|
|
{
|
|
return isWithoutLights[i] && isThereSpace[i];
|
|
}
|
|
|
|
public Crossroads this[int i]
|
|
{
|
|
get {
|
|
switch(i)
|
|
{
|
|
case 0:
|
|
return roadSystem.NW;
|
|
case 1:
|
|
return roadSystem.NE;
|
|
case 2:
|
|
return roadSystem.SE;
|
|
default:
|
|
return roadSystem.SW;
|
|
}
|
|
}
|
|
}
|
|
}
|