255 lines
6.6 KiB
C#
255 lines
6.6 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://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<CrossroadUnity> crossroadsUnity;
|
|
private CrossroadPython[] crossroadsPython;
|
|
|
|
[Header("Misc setup")]
|
|
public GameObject carPrefab;
|
|
public List<Color> 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<CrossroadPython>(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<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 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<T> (string json)
|
|
{
|
|
Wrapper<T> wrapper = JsonUtility.FromJson<Wrapper<T>>(json);
|
|
return wrapper.Items;
|
|
}
|
|
|
|
public static string ToJson<T> (T[] array)
|
|
{
|
|
Wrapper<T> wrapper = new Wrapper<T>();
|
|
wrapper.Items = array;
|
|
return JsonUtility.ToJson(wrapper);
|
|
}
|
|
|
|
public static string ToJson<T> (T[] array, bool prettyPrint)
|
|
{
|
|
Wrapper<T> wrapper = new Wrapper<T>();
|
|
wrapper.Items = array;
|
|
return JsonUtility.ToJson(wrapper, prettyPrint);
|
|
}
|
|
|
|
[System.Serializable]
|
|
private class Wrapper<T>
|
|
{
|
|
public T[] Items;
|
|
}
|
|
}
|