Initial
This commit is contained in:
commit
36a53f343e
5 changed files with 300431 additions and 0 deletions
0
UnityProject/Scripts/.gitkeep
Normal file
0
UnityProject/Scripts/.gitkeep
Normal file
295
UnityProject/Scripts/CarHL.cs
Normal file
295
UnityProject/Scripts/CarHL.cs
Normal file
|
|
@ -0,0 +1,295 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
/* High-level car controller
|
||||
* Az autót irányító állapotgép.
|
||||
*
|
||||
* Jelölések: public PascalCase : futásidejű "interface"
|
||||
* public camelCase : Unityből állítható konstansok
|
||||
*
|
||||
* Megkötések:
|
||||
* Két kanyar nem lehet közvetlen egymás mellett.
|
||||
* A 10-es rétegen az útjelek, a 9-esen az autók legyenek.
|
||||
*
|
||||
* Az itt lévő logika nem túl bonyolult. Igazából 3 állapotgép van, ezek hierarchikusan vannak szervezve.
|
||||
* Könnyen bővíthető plusz állapotokkal, úttipusokkal, közlekedési helyezetekkel.
|
||||
*
|
||||
* Networking az autószínen kívül nincs benne. A kód csak a szerver oldalán fut.
|
||||
*
|
||||
* A tájékozódáshoz raycastingot használ, ezért megfelelő trigger collidereket kell elhelyezni speciális helyeken.
|
||||
* A "junctionAssets/prefabs/roads" mappában látható erre példa.
|
||||
* Szükség esetén a raycasting használat kicsit leljebb szorítható, ha csak nagyon gyenge CPU-nk van.
|
||||
*
|
||||
* Csak akkor áll meg másik autó miatt, ha az irányvektorik 90° > szöget zárnak be.
|
||||
*
|
||||
* A kereszteződéseket leszámítva a pálya segítségével magától közlekedik.
|
||||
* Keresztetződéshez érve a TrafficController-től kérdezi meg, hogy merre mehet.
|
||||
*/
|
||||
|
||||
//Kizárólag az autó színét szinkronizálja
|
||||
[NetworkSettings(channel = 0, sendInterval = 0.1f)]
|
||||
public class CarHL : NetworkBehaviour
|
||||
{
|
||||
/* Controls */ //Ezeken kívűl más nem kell a futásidejű irányításához, a többit magától megoldja.
|
||||
[SyncVar(hook = "changeColor")]
|
||||
public Color CarColor;
|
||||
|
||||
//Jelenleg melyik úton van?
|
||||
public int RoadID;
|
||||
/**/
|
||||
|
||||
[Header("Sensors")]
|
||||
public float carSensorLength = 7;
|
||||
public float roadSensorLength = 5;
|
||||
public Vector3 driverSensorOffset;
|
||||
//Driver szenzor széttartás
|
||||
public float deltaX = 0.2f;
|
||||
|
||||
//Innen indulnak a raycastok
|
||||
private Vector3 driverSensor;
|
||||
|
||||
[Header("External references")]
|
||||
public string trafficContollerName = "Traffic controller";
|
||||
public Renderer body;
|
||||
public CarLL carLL;
|
||||
private TrafficController traffic;
|
||||
|
||||
[Header("Misc")]
|
||||
public float turningChance = 0.5f;
|
||||
|
||||
//Állapotgépek
|
||||
//Fő állapot
|
||||
private CarState carState;
|
||||
//Az úton ilyen állapotban van
|
||||
private RoadCarState roadCarState;
|
||||
//A kereszteződésben ilyen állapotban van
|
||||
private CrossroadCarState crossroadCarState;
|
||||
|
||||
//A következő utak ID-je.
|
||||
private int rightRoadID;
|
||||
private int forwardRoadID;
|
||||
|
||||
public void Start ()
|
||||
{
|
||||
changeColor(CarColor);
|
||||
|
||||
if (!isServer) return;
|
||||
|
||||
traffic = GameObject.Find(trafficContollerName).GetComponent<TrafficController>();
|
||||
|
||||
//Alapállapot
|
||||
carState = CarState.road;
|
||||
roadCarState = RoadCarState.onRoad;
|
||||
}
|
||||
|
||||
public void FixedUpdate ()
|
||||
{
|
||||
//Ez az egész modul (a színváltást leszámítva) kliens oldalon nem csinál semmit.
|
||||
if (!isServer) return;
|
||||
|
||||
//Innen indulnak a raycastok
|
||||
driverSensor = transform.position + transform.forward * driverSensorOffset.x +
|
||||
transform.right * driverSensorOffset.z + transform.up * driverSensorOffset.y;
|
||||
|
||||
/* A raycastok Debugban:
|
||||
* piros : nem talált el semmi lényegeset
|
||||
* kék : autót talált, de szembejövő, szóval ignore
|
||||
* zöld : meg kell állni miatta
|
||||
*/
|
||||
|
||||
//Itt tárolódnak a raycastok
|
||||
RaycastHit hit;
|
||||
|
||||
switch (carState)
|
||||
{
|
||||
case CarState.road:
|
||||
carLL.IsBraking = shouldStopOfCar();
|
||||
|
||||
switch (roadCarState)
|
||||
{
|
||||
case RoadCarState.onRoad:
|
||||
|
||||
if (Physics.Raycast(driverSensor, -transform.up, out hit, roadSensorLength, 1 << 10))
|
||||
{
|
||||
if (hit.collider)
|
||||
{
|
||||
Debug.DrawLine(driverSensor, hit.point, Color.green);
|
||||
|
||||
if (hit.collider.tag == "rightTurn")
|
||||
{
|
||||
carLL.StartTurning(false);
|
||||
roadCarState = RoadCarState.onTurn;
|
||||
}
|
||||
else if (hit.collider.tag == "leftTurn")
|
||||
{
|
||||
carLL.StartTurning(true);
|
||||
roadCarState = RoadCarState.onTurn;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
//Erre az állapotra azért van szükség, hogy csak egyszer triggerelődjön a StartTurning
|
||||
case RoadCarState.onTurn:
|
||||
if (carLL.IsTurningDone())
|
||||
roadCarState = RoadCarState.onRoad;
|
||||
break;
|
||||
}
|
||||
|
||||
/* KÖZÖS az összes roadStateben, hogy figyel a kereszteződésre. */
|
||||
//Amúgy ez a feature nincsen kihasználva, de a jövőben lehet, hogy ez megváltozik.
|
||||
if (Physics.Raycast(driverSensor, transform.forward, out hit, roadSensorLength, 1 << 10))
|
||||
if (hit.collider)
|
||||
for (int i = 0; i < 4; i++)
|
||||
if (hit.collider.tag == "crossRoad" + i)
|
||||
{
|
||||
carState = CarState.crossroad;
|
||||
crossroadCarState = CrossroadCarState.beforeLightWaiting;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case CarState.crossroad:
|
||||
//Ez az alapértelmezett
|
||||
carLL.IsBraking = true;
|
||||
|
||||
switch (crossroadCarState)
|
||||
{
|
||||
case CrossroadCarState.beforeLightWaiting:
|
||||
if (Physics.Raycast(driverSensor, transform.forward, out hit, roadSensorLength, 1 << 10))
|
||||
if (hit.collider)
|
||||
Debug.DrawLine(driverSensor, hit.point, Color.blue);
|
||||
for (int i = 0; i < 4; i++)
|
||||
if (hit.collider.tag == "crossRoad" + i)
|
||||
if (traffic.getInfo(i, hit.collider.name, ref forwardRoadID, ref rightRoadID))
|
||||
crossroadCarState = CrossroadCarState.beforeLightStarting;
|
||||
|
||||
break;
|
||||
|
||||
case CrossroadCarState.beforeLightStarting:
|
||||
crossroadCarState = CrossroadCarState.beforeLightWaiting;
|
||||
|
||||
if (Random.Range(0.0f, 1.0f) < turningChance)
|
||||
{
|
||||
if (traffic.changeRoad(RoadID, rightRoadID))
|
||||
{
|
||||
RoadID = rightRoadID;
|
||||
crossroadCarState = CrossroadCarState.preManouverRight;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (traffic.changeRoad(RoadID, forwardRoadID))
|
||||
{
|
||||
RoadID = forwardRoadID;
|
||||
crossroadCarState = CrossroadCarState.preManouverForward;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
//Maga az áthaladás azonos, a lényeg, hogy előtte be kell gurulni a kereszteződésbe, és csak utána
|
||||
//lehet elkezdeni.
|
||||
case CrossroadCarState.preManouverForward:
|
||||
carLL.IsBraking = false;
|
||||
if (Physics.Raycast(driverSensor, -transform.up, out hit, roadSensorLength, 1 << 10))
|
||||
if (hit.collider && hit.collider.tag == "crossRoad")
|
||||
crossroadCarState = CrossroadCarState.manouver;
|
||||
break;
|
||||
|
||||
case CrossroadCarState.preManouverRight:
|
||||
carLL.IsBraking = false;
|
||||
if (Physics.Raycast(driverSensor, -transform.up, out hit, roadSensorLength, 1 << 10))
|
||||
if (hit.collider && hit.collider.tag == "crossRoad")
|
||||
{
|
||||
carLL.StartTurning(false);
|
||||
crossroadCarState = CrossroadCarState.manouver;
|
||||
}
|
||||
break;
|
||||
|
||||
case CrossroadCarState.manouver:
|
||||
carLL.IsBraking = false;
|
||||
if (Physics.Raycast(driverSensor, -transform.up, out hit, roadSensorLength, 1 << 10))
|
||||
if (hit.collider && hit.collider.tag != "crossRoad")
|
||||
carState = CarState.road;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void changeColor (Color newColor)
|
||||
{
|
||||
body.materials[1].color = newColor;
|
||||
}
|
||||
|
||||
private bool shouldStopOfCar ()
|
||||
{
|
||||
RaycastHit hit;
|
||||
|
||||
//Az autók a 9-es rétegen vannak
|
||||
|
||||
//Ezt lehetne változóba tenni, de ez működik, szóval nem kell megváltoztatni.
|
||||
//Ha gond a szerveroldali CPU használat, akkor ezen kell javítani.
|
||||
for (int i = -3; i <= 3; i++)
|
||||
{
|
||||
Debug.DrawLine(driverSensor, driverSensor + ( Quaternion.Euler(0, deltaX * i, 0) * transform.forward * carSensorLength ), Color.red);
|
||||
if (Physics.Raycast(driverSensor, Quaternion.Euler(0, deltaX * i, 0) * transform.forward, out hit, carSensorLength, 1 << 9, QueryTriggerInteraction.Collide))
|
||||
{
|
||||
Debug.DrawLine(driverSensor, hit.point, Color.blue);
|
||||
float angle = Mathf.Abs(transform.eulerAngles.y - hit.collider.transform.eulerAngles.y);
|
||||
if (angle >= 180) angle -= 360;
|
||||
angle = Mathf.Abs(angle);
|
||||
|
||||
if (hit.collider.tag == "car" && angle < 90)
|
||||
{
|
||||
Debug.DrawLine(driverSensor, hit.point, Color.green);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//A vezető szemét jelképező gömb rajzolása
|
||||
private void OnDrawGizmos ()
|
||||
{
|
||||
driverSensor = transform.position + transform.forward * driverSensorOffset.x +
|
||||
transform.right * driverSensorOffset.z + transform.up * driverSensorOffset.y;
|
||||
Gizmos.DrawSphere(driverSensor, 0.15f);
|
||||
}
|
||||
|
||||
//Robbanás
|
||||
private void OnTriggerEnter (Collider other)
|
||||
{
|
||||
if (!isServer) return;
|
||||
|
||||
if (other.tag == "car")
|
||||
{
|
||||
carLL.ShouldExplode = true;
|
||||
traffic.roads[RoadID].carCount--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum CarState
|
||||
{
|
||||
road,
|
||||
crossroad
|
||||
}
|
||||
|
||||
public enum RoadCarState
|
||||
{
|
||||
onRoad,
|
||||
onTurn
|
||||
}
|
||||
|
||||
public enum CrossroadCarState
|
||||
{
|
||||
beforeLightWaiting,
|
||||
beforeLightStarting,
|
||||
preManouverForward,
|
||||
preManouverRight,
|
||||
manouver
|
||||
}
|
||||
255
UnityProject/Scripts/CarLL.cs
Normal file
255
UnityProject/Scripts/CarLL.cs
Normal file
|
|
@ -0,0 +1,255 @@
|
|||
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;
|
||||
}
|
||||
}
|
||||
255
UnityProject/Scripts/TrafficController.cs
Normal file
255
UnityProject/Scripts/TrafficController.cs
Normal file
|
|
@ -0,0 +1,255 @@
|
|||
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;
|
||||
}
|
||||
}
|
||||
BIN
UnityProject/Scripts/other.zip
Normal file
BIN
UnityProject/Scripts/other.zip
Normal file
Binary file not shown.
Loading…
Reference in a new issue