diff --git a/Assets/Materials/InFront.mat b/Assets/Materials/InFront.mat index 733df81..88a1283 100644 --- a/Assets/Materials/InFront.mat +++ b/Assets/Materials/InFront.mat @@ -8,7 +8,7 @@ m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_Name: InFront - m_Shader: {fileID: 4800000, guid: f29180dc31569f94f92bb39aa3f95f71, type: 3} + m_Shader: {fileID: 10755, guid: 0000000000000000f000000000000000, type: 0} m_ShaderKeywords: _GLOSSYREFLECTIONS_OFF _SPECULARHIGHLIGHTS_OFF m_LightmapFlags: 4 m_EnableInstancingVariants: 0 diff --git a/Assets/Materials/InFront.mat b/Assets/Materials/InFront.mat index 733df81..88a1283 100644 --- a/Assets/Materials/InFront.mat +++ b/Assets/Materials/InFront.mat @@ -8,7 +8,7 @@ m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_Name: InFront - m_Shader: {fileID: 4800000, guid: f29180dc31569f94f92bb39aa3f95f71, type: 3} + m_Shader: {fileID: 10755, guid: 0000000000000000f000000000000000, type: 0} m_ShaderKeywords: _GLOSSYREFLECTIONS_OFF _SPECULARHIGHLIGHTS_OFF m_LightmapFlags: 4 m_EnableInstancingVariants: 0 diff --git a/Assets/Scenes/SampleScene.unity b/Assets/Scenes/SampleScene.unity index e754f09..f902221 100644 --- a/Assets/Scenes/SampleScene.unity +++ b/Assets/Scenes/SampleScene.unity @@ -1178,7 +1178,7 @@ - {fileID: 1551909214} - {fileID: 861726358} timeLeft: 0 - interval: 5 + interval: 2 --- !u!1 &1256630289 GameObject: m_ObjectHideFlags: 0 @@ -1357,7 +1357,7 @@ - {fileID: 496844665} - {fileID: 861726358} timeLeft: 0 - interval: 5 + interval: 2 --- !u!1 &1551909212 GameObject: m_ObjectHideFlags: 0 @@ -1634,7 +1634,7 @@ - {fileID: 496844665} - {fileID: 1551909214} timeLeft: 0 - interval: 5 + interval: 2 --- !u!1 &2127136779 GameObject: m_ObjectHideFlags: 0 @@ -1684,4 +1684,4 @@ - {fileID: 496844665} - {fileID: 861726358} timeLeft: 0 - interval: 3 + interval: 2 diff --git a/Assets/Materials/InFront.mat b/Assets/Materials/InFront.mat index 733df81..88a1283 100644 --- a/Assets/Materials/InFront.mat +++ b/Assets/Materials/InFront.mat @@ -8,7 +8,7 @@ m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_Name: InFront - m_Shader: {fileID: 4800000, guid: f29180dc31569f94f92bb39aa3f95f71, type: 3} + m_Shader: {fileID: 10755, guid: 0000000000000000f000000000000000, type: 0} m_ShaderKeywords: _GLOSSYREFLECTIONS_OFF _SPECULARHIGHLIGHTS_OFF m_LightmapFlags: 4 m_EnableInstancingVariants: 0 diff --git a/Assets/Scenes/SampleScene.unity b/Assets/Scenes/SampleScene.unity index e754f09..f902221 100644 --- a/Assets/Scenes/SampleScene.unity +++ b/Assets/Scenes/SampleScene.unity @@ -1178,7 +1178,7 @@ - {fileID: 1551909214} - {fileID: 861726358} timeLeft: 0 - interval: 5 + interval: 2 --- !u!1 &1256630289 GameObject: m_ObjectHideFlags: 0 @@ -1357,7 +1357,7 @@ - {fileID: 496844665} - {fileID: 861726358} timeLeft: 0 - interval: 5 + interval: 2 --- !u!1 &1551909212 GameObject: m_ObjectHideFlags: 0 @@ -1634,7 +1634,7 @@ - {fileID: 496844665} - {fileID: 1551909214} timeLeft: 0 - interval: 5 + interval: 2 --- !u!1 &2127136779 GameObject: m_ObjectHideFlags: 0 @@ -1684,4 +1684,4 @@ - {fileID: 496844665} - {fileID: 861726358} timeLeft: 0 - interval: 3 + interval: 2 diff --git a/Assets/Scripts/Car/Car.cs b/Assets/Scripts/Car/Car.cs index 8e12601..07dfb2e 100644 --- a/Assets/Scripts/Car/Car.cs +++ b/Assets/Scripts/Car/Car.cs @@ -11,12 +11,15 @@ private Config config; public Vector3 position, direction; public bool isAlive = true; + private CarData carData; public Car(Route route, Transform parent, Config config) { this.route = route; this.config = config; road = route.roads[0]; - road.cars.Add(this); + foreach (Road currentRoad in route.roads) { + currentRoad.carsOnRoute.Add(this); + } gameObject = new GameObject(); FlatCircleRenderer renderer = new FlatCircleRenderer(0.8f, 0.2f, 32, 0.01f); @@ -29,76 +32,120 @@ carMesh.AddComponent().material = config.carMaterial; carMesh.AddComponent().mesh = config.carMesh; carMesh.transform.parent = gameObject.transform; - CarData carData = gameObject.AddComponent(); + carData = gameObject.AddComponent(); carData.car = this; position = road.path.getPosition(0f); carData.Update(); brakingAcceleration = 0.2f * -Physics.gravity.y; acceleration = config.carTorque / (config.carWheelRadius * config.carMass); - airResistance = config.carAirResistanceModifier*config.carFrontalArea*config.airDensity / - (2*config.carMass); + airResistance = config.carAirResistanceModifier * config.carFrontalArea * config.airDensity / + (2 * config.carMass); } private void incrementRoad() { roadPositon -= road.path.length; roadIndex++; - road.cars.Remove(this); + road.carsOnRoute.Remove(this); if (roadIndex == route.roads.Count) { GameObject.Destroy(gameObject); isAlive = false; return; } road = route.roads[roadIndex]; - road.cars.Add(this); } private float getMaxSpeed(Road road, float distance) { - return Mathf.Sqrt((float) (-Mathf.Abs(road.path.getRadius(road.path.getT(distance))) / + return Mathf.Sqrt((float)(-Mathf.Abs(road.path.getRadius(road.path.getT(distance))) / 0.2 * Physics.gravity.y)); } private bool needsBraking(float totalDistance, float maxSpeed) { + if (totalDistance < 0) { + return true; + } float deltaV = speed - maxSpeed; float distanceNeededToBrake = speed * speed / brakingAcceleration - 0.5f * deltaV * deltaV / brakingAcceleration; - return totalDistance < distanceNeededToBrake; + return totalDistance <= distanceNeededToBrake; + } + + private float getDistance(Car car) { + if (car.road == this.road) { + //return this.roadPositon - car.roadPositon; + } + Road commonRoad = car.road; + float otherPosition = car.roadPositon; + for (int i = car.roadIndex; !this.route.roads.Contains(commonRoad) || + this.roadIndex > this.route.roads.IndexOf(commonRoad); i++) { + commonRoad = car.route.roads[i]; + otherPosition -= commonRoad.path.length; + } + float ownPosition = this.roadPositon; + for (int i = this.roadIndex ; this.route.roads[i] != commonRoad; i++) { + ownPosition -= this.route.roads[i].path.length; + } + return otherPosition - ownPosition; + } + + private bool needsBrakingForCar(Car car) { + if (car.road == road && roadPositon > car.roadPositon) { + return false; + } + float distance = getDistance(car); + if (distance <= 0) { + return false; + } + if (distance <= 3) { + return true; + } + return needsBraking(distance-3, car.speed); } private bool isBraking() { float stoppingDistance = 0.5f * speed * speed / brakingAcceleration; + stoppingDistance = Mathf.Min(5f, stoppingDistance); Road currentRoad = road; float currentRoadPosition = roadPositon; int currentRoadIndex = roadIndex; - for (int i = 1; i <= 10; i++) { - currentRoadPosition += stoppingDistance / 10; + List carsToCheck = new List(); + foreach (Car car in currentRoad.carsOnRoute) { + carsToCheck.Add(car); + } + int steps = 30; + for (int i = 1; i <= steps; i++) { + currentRoadPosition += stoppingDistance / steps; + float totalDistance = stoppingDistance / steps * i; while (currentRoadPosition >= currentRoad.path.length) { - currentRoadIndex ++; + currentRoadIndex++; if (currentRoadIndex == route.roads.Count) { - return false; + goto end; } currentRoadPosition -= currentRoad.path.length; currentRoad = route.roads[currentRoadIndex]; + foreach (Car car in currentRoad.carsOnRoute) { + if (!carsToCheck.Contains(car)) { + carsToCheck.Add(car); + } + } } - float totalDistance = stoppingDistance / 10 * i; if (needsBraking(totalDistance, getMaxSpeed(currentRoad, currentRoadPosition))) { return true; } - foreach (Car car in currentRoad.cars) { - if (car != this && - roadPositon < car.roadPositon && - car.roadPositon - 3f <= currentRoadPosition && - needsBraking(totalDistance, car.speed)) { - return true; - } + } + end: + foreach (Car car in carsToCheck) { + if (car != this && needsBrakingForCar(car)) { + return true; } } return false; } - + public void step(float deltaTime) { speed -= airResistance * deltaTime * speed * speed; if (isBraking()) { speed -= brakingAcceleration * deltaTime; + speed = Mathf.Max(0, speed); gameObject.GetComponent().material = config.carBrakingMaterial; } else { speed += acceleration * deltaTime; diff --git a/Assets/Materials/InFront.mat b/Assets/Materials/InFront.mat index 733df81..88a1283 100644 --- a/Assets/Materials/InFront.mat +++ b/Assets/Materials/InFront.mat @@ -8,7 +8,7 @@ m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_Name: InFront - m_Shader: {fileID: 4800000, guid: f29180dc31569f94f92bb39aa3f95f71, type: 3} + m_Shader: {fileID: 10755, guid: 0000000000000000f000000000000000, type: 0} m_ShaderKeywords: _GLOSSYREFLECTIONS_OFF _SPECULARHIGHLIGHTS_OFF m_LightmapFlags: 4 m_EnableInstancingVariants: 0 diff --git a/Assets/Scenes/SampleScene.unity b/Assets/Scenes/SampleScene.unity index e754f09..f902221 100644 --- a/Assets/Scenes/SampleScene.unity +++ b/Assets/Scenes/SampleScene.unity @@ -1178,7 +1178,7 @@ - {fileID: 1551909214} - {fileID: 861726358} timeLeft: 0 - interval: 5 + interval: 2 --- !u!1 &1256630289 GameObject: m_ObjectHideFlags: 0 @@ -1357,7 +1357,7 @@ - {fileID: 496844665} - {fileID: 861726358} timeLeft: 0 - interval: 5 + interval: 2 --- !u!1 &1551909212 GameObject: m_ObjectHideFlags: 0 @@ -1634,7 +1634,7 @@ - {fileID: 496844665} - {fileID: 1551909214} timeLeft: 0 - interval: 5 + interval: 2 --- !u!1 &2127136779 GameObject: m_ObjectHideFlags: 0 @@ -1684,4 +1684,4 @@ - {fileID: 496844665} - {fileID: 861726358} timeLeft: 0 - interval: 3 + interval: 2 diff --git a/Assets/Scripts/Car/Car.cs b/Assets/Scripts/Car/Car.cs index 8e12601..07dfb2e 100644 --- a/Assets/Scripts/Car/Car.cs +++ b/Assets/Scripts/Car/Car.cs @@ -11,12 +11,15 @@ private Config config; public Vector3 position, direction; public bool isAlive = true; + private CarData carData; public Car(Route route, Transform parent, Config config) { this.route = route; this.config = config; road = route.roads[0]; - road.cars.Add(this); + foreach (Road currentRoad in route.roads) { + currentRoad.carsOnRoute.Add(this); + } gameObject = new GameObject(); FlatCircleRenderer renderer = new FlatCircleRenderer(0.8f, 0.2f, 32, 0.01f); @@ -29,76 +32,120 @@ carMesh.AddComponent().material = config.carMaterial; carMesh.AddComponent().mesh = config.carMesh; carMesh.transform.parent = gameObject.transform; - CarData carData = gameObject.AddComponent(); + carData = gameObject.AddComponent(); carData.car = this; position = road.path.getPosition(0f); carData.Update(); brakingAcceleration = 0.2f * -Physics.gravity.y; acceleration = config.carTorque / (config.carWheelRadius * config.carMass); - airResistance = config.carAirResistanceModifier*config.carFrontalArea*config.airDensity / - (2*config.carMass); + airResistance = config.carAirResistanceModifier * config.carFrontalArea * config.airDensity / + (2 * config.carMass); } private void incrementRoad() { roadPositon -= road.path.length; roadIndex++; - road.cars.Remove(this); + road.carsOnRoute.Remove(this); if (roadIndex == route.roads.Count) { GameObject.Destroy(gameObject); isAlive = false; return; } road = route.roads[roadIndex]; - road.cars.Add(this); } private float getMaxSpeed(Road road, float distance) { - return Mathf.Sqrt((float) (-Mathf.Abs(road.path.getRadius(road.path.getT(distance))) / + return Mathf.Sqrt((float)(-Mathf.Abs(road.path.getRadius(road.path.getT(distance))) / 0.2 * Physics.gravity.y)); } private bool needsBraking(float totalDistance, float maxSpeed) { + if (totalDistance < 0) { + return true; + } float deltaV = speed - maxSpeed; float distanceNeededToBrake = speed * speed / brakingAcceleration - 0.5f * deltaV * deltaV / brakingAcceleration; - return totalDistance < distanceNeededToBrake; + return totalDistance <= distanceNeededToBrake; + } + + private float getDistance(Car car) { + if (car.road == this.road) { + //return this.roadPositon - car.roadPositon; + } + Road commonRoad = car.road; + float otherPosition = car.roadPositon; + for (int i = car.roadIndex; !this.route.roads.Contains(commonRoad) || + this.roadIndex > this.route.roads.IndexOf(commonRoad); i++) { + commonRoad = car.route.roads[i]; + otherPosition -= commonRoad.path.length; + } + float ownPosition = this.roadPositon; + for (int i = this.roadIndex ; this.route.roads[i] != commonRoad; i++) { + ownPosition -= this.route.roads[i].path.length; + } + return otherPosition - ownPosition; + } + + private bool needsBrakingForCar(Car car) { + if (car.road == road && roadPositon > car.roadPositon) { + return false; + } + float distance = getDistance(car); + if (distance <= 0) { + return false; + } + if (distance <= 3) { + return true; + } + return needsBraking(distance-3, car.speed); } private bool isBraking() { float stoppingDistance = 0.5f * speed * speed / brakingAcceleration; + stoppingDistance = Mathf.Min(5f, stoppingDistance); Road currentRoad = road; float currentRoadPosition = roadPositon; int currentRoadIndex = roadIndex; - for (int i = 1; i <= 10; i++) { - currentRoadPosition += stoppingDistance / 10; + List carsToCheck = new List(); + foreach (Car car in currentRoad.carsOnRoute) { + carsToCheck.Add(car); + } + int steps = 30; + for (int i = 1; i <= steps; i++) { + currentRoadPosition += stoppingDistance / steps; + float totalDistance = stoppingDistance / steps * i; while (currentRoadPosition >= currentRoad.path.length) { - currentRoadIndex ++; + currentRoadIndex++; if (currentRoadIndex == route.roads.Count) { - return false; + goto end; } currentRoadPosition -= currentRoad.path.length; currentRoad = route.roads[currentRoadIndex]; + foreach (Car car in currentRoad.carsOnRoute) { + if (!carsToCheck.Contains(car)) { + carsToCheck.Add(car); + } + } } - float totalDistance = stoppingDistance / 10 * i; if (needsBraking(totalDistance, getMaxSpeed(currentRoad, currentRoadPosition))) { return true; } - foreach (Car car in currentRoad.cars) { - if (car != this && - roadPositon < car.roadPositon && - car.roadPositon - 3f <= currentRoadPosition && - needsBraking(totalDistance, car.speed)) { - return true; - } + } + end: + foreach (Car car in carsToCheck) { + if (car != this && needsBrakingForCar(car)) { + return true; } } return false; } - + public void step(float deltaTime) { speed -= airResistance * deltaTime * speed * speed; if (isBraking()) { speed -= brakingAcceleration * deltaTime; + speed = Mathf.Max(0, speed); gameObject.GetComponent().material = config.carBrakingMaterial; } else { speed += acceleration * deltaTime; diff --git a/Assets/Scripts/Car/CarData.cs b/Assets/Scripts/Car/CarData.cs index 78b7e5a..dcc16a9 100644 --- a/Assets/Scripts/Car/CarData.cs +++ b/Assets/Scripts/Car/CarData.cs @@ -15,4 +15,8 @@ transform.forward = car.direction; } } + + public void printf(string data) { + print(transform.position.ToString() + " " + data); + } } diff --git a/Assets/Materials/InFront.mat b/Assets/Materials/InFront.mat index 733df81..88a1283 100644 --- a/Assets/Materials/InFront.mat +++ b/Assets/Materials/InFront.mat @@ -8,7 +8,7 @@ m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_Name: InFront - m_Shader: {fileID: 4800000, guid: f29180dc31569f94f92bb39aa3f95f71, type: 3} + m_Shader: {fileID: 10755, guid: 0000000000000000f000000000000000, type: 0} m_ShaderKeywords: _GLOSSYREFLECTIONS_OFF _SPECULARHIGHLIGHTS_OFF m_LightmapFlags: 4 m_EnableInstancingVariants: 0 diff --git a/Assets/Scenes/SampleScene.unity b/Assets/Scenes/SampleScene.unity index e754f09..f902221 100644 --- a/Assets/Scenes/SampleScene.unity +++ b/Assets/Scenes/SampleScene.unity @@ -1178,7 +1178,7 @@ - {fileID: 1551909214} - {fileID: 861726358} timeLeft: 0 - interval: 5 + interval: 2 --- !u!1 &1256630289 GameObject: m_ObjectHideFlags: 0 @@ -1357,7 +1357,7 @@ - {fileID: 496844665} - {fileID: 861726358} timeLeft: 0 - interval: 5 + interval: 2 --- !u!1 &1551909212 GameObject: m_ObjectHideFlags: 0 @@ -1634,7 +1634,7 @@ - {fileID: 496844665} - {fileID: 1551909214} timeLeft: 0 - interval: 5 + interval: 2 --- !u!1 &2127136779 GameObject: m_ObjectHideFlags: 0 @@ -1684,4 +1684,4 @@ - {fileID: 496844665} - {fileID: 861726358} timeLeft: 0 - interval: 3 + interval: 2 diff --git a/Assets/Scripts/Car/Car.cs b/Assets/Scripts/Car/Car.cs index 8e12601..07dfb2e 100644 --- a/Assets/Scripts/Car/Car.cs +++ b/Assets/Scripts/Car/Car.cs @@ -11,12 +11,15 @@ private Config config; public Vector3 position, direction; public bool isAlive = true; + private CarData carData; public Car(Route route, Transform parent, Config config) { this.route = route; this.config = config; road = route.roads[0]; - road.cars.Add(this); + foreach (Road currentRoad in route.roads) { + currentRoad.carsOnRoute.Add(this); + } gameObject = new GameObject(); FlatCircleRenderer renderer = new FlatCircleRenderer(0.8f, 0.2f, 32, 0.01f); @@ -29,76 +32,120 @@ carMesh.AddComponent().material = config.carMaterial; carMesh.AddComponent().mesh = config.carMesh; carMesh.transform.parent = gameObject.transform; - CarData carData = gameObject.AddComponent(); + carData = gameObject.AddComponent(); carData.car = this; position = road.path.getPosition(0f); carData.Update(); brakingAcceleration = 0.2f * -Physics.gravity.y; acceleration = config.carTorque / (config.carWheelRadius * config.carMass); - airResistance = config.carAirResistanceModifier*config.carFrontalArea*config.airDensity / - (2*config.carMass); + airResistance = config.carAirResistanceModifier * config.carFrontalArea * config.airDensity / + (2 * config.carMass); } private void incrementRoad() { roadPositon -= road.path.length; roadIndex++; - road.cars.Remove(this); + road.carsOnRoute.Remove(this); if (roadIndex == route.roads.Count) { GameObject.Destroy(gameObject); isAlive = false; return; } road = route.roads[roadIndex]; - road.cars.Add(this); } private float getMaxSpeed(Road road, float distance) { - return Mathf.Sqrt((float) (-Mathf.Abs(road.path.getRadius(road.path.getT(distance))) / + return Mathf.Sqrt((float)(-Mathf.Abs(road.path.getRadius(road.path.getT(distance))) / 0.2 * Physics.gravity.y)); } private bool needsBraking(float totalDistance, float maxSpeed) { + if (totalDistance < 0) { + return true; + } float deltaV = speed - maxSpeed; float distanceNeededToBrake = speed * speed / brakingAcceleration - 0.5f * deltaV * deltaV / brakingAcceleration; - return totalDistance < distanceNeededToBrake; + return totalDistance <= distanceNeededToBrake; + } + + private float getDistance(Car car) { + if (car.road == this.road) { + //return this.roadPositon - car.roadPositon; + } + Road commonRoad = car.road; + float otherPosition = car.roadPositon; + for (int i = car.roadIndex; !this.route.roads.Contains(commonRoad) || + this.roadIndex > this.route.roads.IndexOf(commonRoad); i++) { + commonRoad = car.route.roads[i]; + otherPosition -= commonRoad.path.length; + } + float ownPosition = this.roadPositon; + for (int i = this.roadIndex ; this.route.roads[i] != commonRoad; i++) { + ownPosition -= this.route.roads[i].path.length; + } + return otherPosition - ownPosition; + } + + private bool needsBrakingForCar(Car car) { + if (car.road == road && roadPositon > car.roadPositon) { + return false; + } + float distance = getDistance(car); + if (distance <= 0) { + return false; + } + if (distance <= 3) { + return true; + } + return needsBraking(distance-3, car.speed); } private bool isBraking() { float stoppingDistance = 0.5f * speed * speed / brakingAcceleration; + stoppingDistance = Mathf.Min(5f, stoppingDistance); Road currentRoad = road; float currentRoadPosition = roadPositon; int currentRoadIndex = roadIndex; - for (int i = 1; i <= 10; i++) { - currentRoadPosition += stoppingDistance / 10; + List carsToCheck = new List(); + foreach (Car car in currentRoad.carsOnRoute) { + carsToCheck.Add(car); + } + int steps = 30; + for (int i = 1; i <= steps; i++) { + currentRoadPosition += stoppingDistance / steps; + float totalDistance = stoppingDistance / steps * i; while (currentRoadPosition >= currentRoad.path.length) { - currentRoadIndex ++; + currentRoadIndex++; if (currentRoadIndex == route.roads.Count) { - return false; + goto end; } currentRoadPosition -= currentRoad.path.length; currentRoad = route.roads[currentRoadIndex]; + foreach (Car car in currentRoad.carsOnRoute) { + if (!carsToCheck.Contains(car)) { + carsToCheck.Add(car); + } + } } - float totalDistance = stoppingDistance / 10 * i; if (needsBraking(totalDistance, getMaxSpeed(currentRoad, currentRoadPosition))) { return true; } - foreach (Car car in currentRoad.cars) { - if (car != this && - roadPositon < car.roadPositon && - car.roadPositon - 3f <= currentRoadPosition && - needsBraking(totalDistance, car.speed)) { - return true; - } + } + end: + foreach (Car car in carsToCheck) { + if (car != this && needsBrakingForCar(car)) { + return true; } } return false; } - + public void step(float deltaTime) { speed -= airResistance * deltaTime * speed * speed; if (isBraking()) { speed -= brakingAcceleration * deltaTime; + speed = Mathf.Max(0, speed); gameObject.GetComponent().material = config.carBrakingMaterial; } else { speed += acceleration * deltaTime; diff --git a/Assets/Scripts/Car/CarData.cs b/Assets/Scripts/Car/CarData.cs index 78b7e5a..dcc16a9 100644 --- a/Assets/Scripts/Car/CarData.cs +++ b/Assets/Scripts/Car/CarData.cs @@ -15,4 +15,8 @@ transform.forward = car.direction; } } + + public void printf(string data) { + print(transform.position.ToString() + " " + data); + } } diff --git a/Assets/Scripts/Roads/Node/Node.cs b/Assets/Scripts/Roads/Node/Node.cs index c3fb970..044a8f0 100644 --- a/Assets/Scripts/Roads/Node/Node.cs +++ b/Assets/Scripts/Roads/Node/Node.cs @@ -23,7 +23,7 @@ nodeCircle.AddComponent().material = config.roadEditMaterial; nodeCircle.AddComponent().mesh = circle.mesh; nodeCircle.transform.parent = gameObject.transform; - nodeCircle.transform.localPosition = Vector3.zero; + nodeCircle.transform.localPosition = new Vector3(0f, 0.01f, 0f); GameObject nodeRoad = new GameObject(); nodeRoad.AddComponent().material = config.roadMaterial; diff --git a/Assets/Materials/InFront.mat b/Assets/Materials/InFront.mat index 733df81..88a1283 100644 --- a/Assets/Materials/InFront.mat +++ b/Assets/Materials/InFront.mat @@ -8,7 +8,7 @@ m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_Name: InFront - m_Shader: {fileID: 4800000, guid: f29180dc31569f94f92bb39aa3f95f71, type: 3} + m_Shader: {fileID: 10755, guid: 0000000000000000f000000000000000, type: 0} m_ShaderKeywords: _GLOSSYREFLECTIONS_OFF _SPECULARHIGHLIGHTS_OFF m_LightmapFlags: 4 m_EnableInstancingVariants: 0 diff --git a/Assets/Scenes/SampleScene.unity b/Assets/Scenes/SampleScene.unity index e754f09..f902221 100644 --- a/Assets/Scenes/SampleScene.unity +++ b/Assets/Scenes/SampleScene.unity @@ -1178,7 +1178,7 @@ - {fileID: 1551909214} - {fileID: 861726358} timeLeft: 0 - interval: 5 + interval: 2 --- !u!1 &1256630289 GameObject: m_ObjectHideFlags: 0 @@ -1357,7 +1357,7 @@ - {fileID: 496844665} - {fileID: 861726358} timeLeft: 0 - interval: 5 + interval: 2 --- !u!1 &1551909212 GameObject: m_ObjectHideFlags: 0 @@ -1634,7 +1634,7 @@ - {fileID: 496844665} - {fileID: 1551909214} timeLeft: 0 - interval: 5 + interval: 2 --- !u!1 &2127136779 GameObject: m_ObjectHideFlags: 0 @@ -1684,4 +1684,4 @@ - {fileID: 496844665} - {fileID: 861726358} timeLeft: 0 - interval: 3 + interval: 2 diff --git a/Assets/Scripts/Car/Car.cs b/Assets/Scripts/Car/Car.cs index 8e12601..07dfb2e 100644 --- a/Assets/Scripts/Car/Car.cs +++ b/Assets/Scripts/Car/Car.cs @@ -11,12 +11,15 @@ private Config config; public Vector3 position, direction; public bool isAlive = true; + private CarData carData; public Car(Route route, Transform parent, Config config) { this.route = route; this.config = config; road = route.roads[0]; - road.cars.Add(this); + foreach (Road currentRoad in route.roads) { + currentRoad.carsOnRoute.Add(this); + } gameObject = new GameObject(); FlatCircleRenderer renderer = new FlatCircleRenderer(0.8f, 0.2f, 32, 0.01f); @@ -29,76 +32,120 @@ carMesh.AddComponent().material = config.carMaterial; carMesh.AddComponent().mesh = config.carMesh; carMesh.transform.parent = gameObject.transform; - CarData carData = gameObject.AddComponent(); + carData = gameObject.AddComponent(); carData.car = this; position = road.path.getPosition(0f); carData.Update(); brakingAcceleration = 0.2f * -Physics.gravity.y; acceleration = config.carTorque / (config.carWheelRadius * config.carMass); - airResistance = config.carAirResistanceModifier*config.carFrontalArea*config.airDensity / - (2*config.carMass); + airResistance = config.carAirResistanceModifier * config.carFrontalArea * config.airDensity / + (2 * config.carMass); } private void incrementRoad() { roadPositon -= road.path.length; roadIndex++; - road.cars.Remove(this); + road.carsOnRoute.Remove(this); if (roadIndex == route.roads.Count) { GameObject.Destroy(gameObject); isAlive = false; return; } road = route.roads[roadIndex]; - road.cars.Add(this); } private float getMaxSpeed(Road road, float distance) { - return Mathf.Sqrt((float) (-Mathf.Abs(road.path.getRadius(road.path.getT(distance))) / + return Mathf.Sqrt((float)(-Mathf.Abs(road.path.getRadius(road.path.getT(distance))) / 0.2 * Physics.gravity.y)); } private bool needsBraking(float totalDistance, float maxSpeed) { + if (totalDistance < 0) { + return true; + } float deltaV = speed - maxSpeed; float distanceNeededToBrake = speed * speed / brakingAcceleration - 0.5f * deltaV * deltaV / brakingAcceleration; - return totalDistance < distanceNeededToBrake; + return totalDistance <= distanceNeededToBrake; + } + + private float getDistance(Car car) { + if (car.road == this.road) { + //return this.roadPositon - car.roadPositon; + } + Road commonRoad = car.road; + float otherPosition = car.roadPositon; + for (int i = car.roadIndex; !this.route.roads.Contains(commonRoad) || + this.roadIndex > this.route.roads.IndexOf(commonRoad); i++) { + commonRoad = car.route.roads[i]; + otherPosition -= commonRoad.path.length; + } + float ownPosition = this.roadPositon; + for (int i = this.roadIndex ; this.route.roads[i] != commonRoad; i++) { + ownPosition -= this.route.roads[i].path.length; + } + return otherPosition - ownPosition; + } + + private bool needsBrakingForCar(Car car) { + if (car.road == road && roadPositon > car.roadPositon) { + return false; + } + float distance = getDistance(car); + if (distance <= 0) { + return false; + } + if (distance <= 3) { + return true; + } + return needsBraking(distance-3, car.speed); } private bool isBraking() { float stoppingDistance = 0.5f * speed * speed / brakingAcceleration; + stoppingDistance = Mathf.Min(5f, stoppingDistance); Road currentRoad = road; float currentRoadPosition = roadPositon; int currentRoadIndex = roadIndex; - for (int i = 1; i <= 10; i++) { - currentRoadPosition += stoppingDistance / 10; + List carsToCheck = new List(); + foreach (Car car in currentRoad.carsOnRoute) { + carsToCheck.Add(car); + } + int steps = 30; + for (int i = 1; i <= steps; i++) { + currentRoadPosition += stoppingDistance / steps; + float totalDistance = stoppingDistance / steps * i; while (currentRoadPosition >= currentRoad.path.length) { - currentRoadIndex ++; + currentRoadIndex++; if (currentRoadIndex == route.roads.Count) { - return false; + goto end; } currentRoadPosition -= currentRoad.path.length; currentRoad = route.roads[currentRoadIndex]; + foreach (Car car in currentRoad.carsOnRoute) { + if (!carsToCheck.Contains(car)) { + carsToCheck.Add(car); + } + } } - float totalDistance = stoppingDistance / 10 * i; if (needsBraking(totalDistance, getMaxSpeed(currentRoad, currentRoadPosition))) { return true; } - foreach (Car car in currentRoad.cars) { - if (car != this && - roadPositon < car.roadPositon && - car.roadPositon - 3f <= currentRoadPosition && - needsBraking(totalDistance, car.speed)) { - return true; - } + } + end: + foreach (Car car in carsToCheck) { + if (car != this && needsBrakingForCar(car)) { + return true; } } return false; } - + public void step(float deltaTime) { speed -= airResistance * deltaTime * speed * speed; if (isBraking()) { speed -= brakingAcceleration * deltaTime; + speed = Mathf.Max(0, speed); gameObject.GetComponent().material = config.carBrakingMaterial; } else { speed += acceleration * deltaTime; diff --git a/Assets/Scripts/Car/CarData.cs b/Assets/Scripts/Car/CarData.cs index 78b7e5a..dcc16a9 100644 --- a/Assets/Scripts/Car/CarData.cs +++ b/Assets/Scripts/Car/CarData.cs @@ -15,4 +15,8 @@ transform.forward = car.direction; } } + + public void printf(string data) { + print(transform.position.ToString() + " " + data); + } } diff --git a/Assets/Scripts/Roads/Node/Node.cs b/Assets/Scripts/Roads/Node/Node.cs index c3fb970..044a8f0 100644 --- a/Assets/Scripts/Roads/Node/Node.cs +++ b/Assets/Scripts/Roads/Node/Node.cs @@ -23,7 +23,7 @@ nodeCircle.AddComponent().material = config.roadEditMaterial; nodeCircle.AddComponent().mesh = circle.mesh; nodeCircle.transform.parent = gameObject.transform; - nodeCircle.transform.localPosition = Vector3.zero; + nodeCircle.transform.localPosition = new Vector3(0f, 0.01f, 0f); GameObject nodeRoad = new GameObject(); nodeRoad.AddComponent().material = config.roadMaterial; diff --git a/Assets/Scripts/Roads/Road.cs b/Assets/Scripts/Roads/Road.cs index 032bed8..0489387 100644 --- a/Assets/Scripts/Roads/Road.cs +++ b/Assets/Scripts/Roads/Road.cs @@ -10,7 +10,7 @@ private Config config; private MeshCollider collider; public GameObject gameObject; - public List cars = new List(); + public List carsOnRoute = new List(); public Road(Node start, Node end, Config config) { nodes.Add(start); @@ -35,7 +35,7 @@ gameObject.transform.position = Vector3.zero; GameObject lineChild = new GameObject(); - lineChild.transform.position = Vector3.zero; + lineChild.transform.position = new Vector3(0f, 0.01f, 0f); lineChild.AddComponent().material = config.roadEditMaterial; lineChild.AddComponent().mesh = pathLine.mesh; lineChild.transform.parent = gameObject.transform; @@ -58,7 +58,7 @@ private void setupArrow(FlatBezierRenderer renderer, Transform parent) { GameObject child = new GameObject(); - child.transform.position = Vector3.zero; + child.transform.position = new Vector3(0f, 0.01f, 0f); child.AddComponent().material = config.roadEditMaterial; child.AddComponent().mesh = renderer.mesh; child.transform.parent = parent;