make cars brake to avoid a collision with the car in front
1 parent e69b125 commit f4384919bf35d3d6218afa0511ec0b7af53e159a
@biosfood biosfood authored on 21 Feb 2022
Showing 2 changed files
View
2
■■■
Assets/Scenes/SampleScene.unity
- {fileID: 1551909214}
- {fileID: 496844665}
- {fileID: 861726358}
timeLeft: 0
interval: 5
interval: 3
View
60
Assets/Scripts/Car/Car.cs
using UnityEngine;
 
public class Car {
private Route route;
public Road currentRoad;
public Road road;
public float roadPositon = 0f, speed = 0f, brakingAcceleration, acceleration, airResistance, t;
private int roadIndex = 0;
private GameObject gameObject;
private Config config;
 
public Car(Route route, Transform parent, Config config) {
this.route = route;
this.config = config;
currentRoad = route.roads[0];
currentRoad.cars.Add(this);
road = route.roads[0];
road.cars.Add(this);
 
gameObject = new GameObject();
FlatCircleRenderer renderer = new FlatCircleRenderer(0.8f, 0.2f, 32, 0.01f);
MeshRenderer meshRenderer = gameObject.AddComponent<MeshRenderer>();
carMesh.AddComponent<MeshFilter>().mesh = config.carMesh;
carMesh.transform.parent = gameObject.transform;
CarData carData = gameObject.AddComponent<CarData>();
carData.car = this;
position = currentRoad.path.getPosition(0f);
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);
}
 
private void incrementRoad() {
roadPositon -= currentRoad.path.length;
roadPositon -= road.path.length;
roadIndex++;
road.cars.Remove(this);
if (roadIndex == route.roads.Count) {
GameObject.Destroy(gameObject);
isAlive = false;
return;
}
currentRoad.cars.Remove(this);
currentRoad = route.roads[roadIndex];
currentRoad.cars.Add(this);
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))) /
0.2 * Physics.gravity.y));
}
 
private bool needsBraking(float totalDistance, float maxSpeed) {
float deltaV = speed - maxSpeed;
float distanceNeededToBrake = speed * speed / brakingAcceleration
- 0.5f * deltaV * deltaV / brakingAcceleration;
return totalDistance < distanceNeededToBrake;
}
 
private bool isBraking() {
float stoppingDistance = 0.5f * speed * speed / brakingAcceleration;
Road road = currentRoad;
float position = roadPositon;
Road currentRoad = road;
float currentRoadPosition = roadPositon;
int currentRoadIndex = roadIndex;
for (int i = 1; i <= 10; i++) {
position += stoppingDistance / 10;
while (position >= road.path.length) {
currentRoadPosition += stoppingDistance / 10;
while (currentRoadPosition >= currentRoad.path.length) {
currentRoadIndex ++;
if (currentRoadIndex == route.roads.Count) {
return false;
}
position -= road.path.length;
road = route.roads[currentRoadIndex];
currentRoadPosition -= currentRoad.path.length;
currentRoad = route.roads[currentRoadIndex];
}
float deltaV = speed - getMaxSpeed(road, position);
float distanceNeededToBrake = speed * speed / brakingAcceleration
- 0.5f * deltaV * deltaV / brakingAcceleration;
if (stoppingDistance / 10 * i < distanceNeededToBrake) {
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;
}
}
}
return false;
}
speed += acceleration * deltaTime;
gameObject.GetComponent<MeshRenderer>().material = config.carAccelerationMaterial;
}
roadPositon += deltaTime * speed;
while (roadPositon > currentRoad.path.length) {
while (roadPositon > road.path.length) {
incrementRoad();
}
t = currentRoad.path.getT(roadPositon);
position = currentRoad.path.getPosition(t);
direction = currentRoad.path.getDirection(t);
t = road.path.getT(roadPositon);
position = road.path.getPosition(t);
direction = road.path.getDirection(t);
direction.Normalize();
}
}