目录
1.示意图
1.1行驶路线与红绿灯
2. 层级面板
2.1红绿灯
2.2车辆路径点
3.属性面板
3.1红绿灯
3.2路径点
4.脚本代码
4.1 控制脚本
4.2红绿灯脚本
4.3路径点脚本
4.4车辆控制脚本
5.实现效果
除了四个角-其余路口均有4个路径点
using UnityEngine;
public class RoadContr : MonoBehaviour
{
public TrafficLight[] trafficLights; // 红绿灯数组
public WayPoint[] wayPoints; //路径
public Transform pare;
[SerializeField]
private Map_Car[] fabCar;
private int carNum = 0;
private void OnEnable()
{
InvokeRepeating("CarCreate", 1, 1);
}
private void CarCreate()
{
if (carNum < 50)
{
carNum++;
Map_Car car = Instantiate(fabCar[Random.Range(0, 10)], pare);
WayPoint way = wayPoints[Random.Range(0, wayPoints.Length)];
car.transform.position = way.transform.position;
car.Init(way);
}
else
{
CancelInvoke("CarCreate");
}
}
}
using UnityEngine;
public class TrafficLight : MonoBehaviour
{
private bool isBegin = false;
private float redTime;
public bool isRed = false;
private void OnEnable()
{
redTime = Random.Range(3, 15);
isBegin = true;
}
private void Update()
{
if (!isBegin)
{
return;
}
redTime -= Time.deltaTime;
if (redTime <= 0)
{
isRed = !isRed;
redTime = Random.Range(3, 15);
}
}
}
using System.Collections.Generic;
using UnityEngine;
public class WayPoint : MonoBehaviour
{
[Header("0上1下2左3右")]
[SerializeField]
private List Direction = new();
[Header("下一路径点")]
public List nextWayPoints_1;
public List nextWayPoints_2;
[Header("当前路径点所属红绿灯")]
public TrafficLight trafficLight;
///
/// 0上1下2左3右
///
[HideInInspector]
public int directionSelect = -1;
private int randomNum = -1;
///
/// 获取下一路径点
///
///
public WayPoint GetNextWayPoint()
{
if (Direction.Count == 1)
{
directionSelect = Direction[0];
if (nextWayPoints_1.Count == 1)
{
return nextWayPoints_1[0];
}
else
{
return nextWayPoints_1[Random.value < 0.5 ? 0 : 1];
}
}
else
{
randomNum = Random.value < 0.5 ? 0 : 1;
directionSelect = Direction[randomNum];
if (randomNum == 0)
{
if (nextWayPoints_1.Count == 1)
{
return nextWayPoints_1[0];
}
else
{
return nextWayPoints_1[Random.value < 0.5 ? 0 : 1];
}
}
else
{
if (nextWayPoints_2.Count == 1)
{
return nextWayPoints_2[0];
}
else
{
return nextWayPoints_2[Random.value < 0.5 ? 0 : 1];
}
}
}
}
}
using UnityEngine;
public class Map_Car : MonoBehaviour
{
private WayPoint curWay; // 当前路径点
private WayPoint nextWay; // 下一路径点
private TrafficLight trafficLight;
public float moveSpeed = 3f; // 车辆移动速度
public float minDistance = 2f; // 最小车距
private bool canMove = true;
private bool isBegin = false;
private Vector3 nextWaypointPos;
private Quaternion currentWaypointRot;
private Vector3 targetDirection;
[SerializeField]
private int direction = -1;
public void Init(WayPoint cur_way)
{
curWay = cur_way;
nextWay = curWay.GetNextWayPoint();
trafficLight = curWay.trafficLight;
nextWaypointPos = nextWay.transform.position;
direction = curWay.directionSelect;
switch (direction)
{
case 0:
currentWaypointRot = Quaternion.Euler(0, 180, 0);
break;
case 1:
currentWaypointRot = Quaternion.Euler(0, 0, 0);
break;
case 2:
currentWaypointRot = Quaternion.Euler(0, 90, 0);
break;
case 3:
currentWaypointRot = Quaternion.Euler(0, 270, 0);
break;
}
// 计算车辆朝向下一个路径点的方向
targetDirection = nextWaypointPos - transform.position;
targetDirection.y = 0f; // 将方向的y轴分量设为0,使车辆在平面上移动
targetDirection.Normalize(); // 归一化方向向量
isBegin = true;
}
private void Update()
{
if (!isBegin) { return; }
// 如果车辆离当前路径点很近,则停下来等待红灯
if (Vector3.Distance(transform.position, nextWaypointPos) <= 2.5f)
{
// 获取当前路口的红绿灯状态
if (trafficLight.isRed)
{
switch (direction)
{
case 0:
case 1:
canMove = false;
break;
case 2:
case 3:
canMove = true;
break;
}
}
else
{
switch (direction)
{
case 0:
case 1:
canMove = true;
break;
case 2:
case 3:
canMove = false;
break;
}
}
if (Vector3.Distance(transform.position, nextWaypointPos) <= 0.1f)
{
Init(nextWay);
}
}
if (canMove)
{
// 否则,根据车辆移动速度向前移动
transform.Translate(targetDirection * moveSpeed * Time.deltaTime, Space.World);
transform.rotation = Quaternion.Lerp(transform.rotation, currentWaypointRot, 0.1f); // 平滑旋转到目标方向
// 检查前方是否有其他车辆,并保持车距
RaycastHit hit;
if (Physics.Raycast(transform.position, -transform.forward, out hit, minDistance))
{
moveSpeed = 0f;
//Debug.DrawRay(transform.position, -transform.forward * minDistance, Color.red);
}
else
{
// 否则,继续移动
moveSpeed = 3f; // 恢复车辆移动速度
//Debug.DrawRay(transform.position, -transform.forward * minDistance, Color.green);
}
}
}
}
城市道路