using Config.config; using Sirenix.OdinInspector; using System.Collections.Generic; using Unity.VisualScripting; using UnityEngine; using UnityEngine.Rendering; /// /// 路段_生成NPC车辆 /// public partial class SectionRoad { /// /// 占用车道列表 /// public List occupationIndex = new List(); /// /// 排除已换的车辆 /// private List exclude; /// /// 记录变道车辆 /// private List record; /// /// 生成NPC车 /// public void GenerateNPCCar(List ints, LevelConfig levelConfig) { PutCar(); for (int i = 0; i < ints.Count; i++) { GenerateRoundNPCCar(levelConfig, generatePoints[ints[i]]); } } /// /// 指定位置生成车 /// /// public NPCCar GenerateNPCCar(Vector3 pos,string skinCarID) { NPCCar npcCar =CachePoolManager.Instance.Take(YooAssetManager.Instance.LoadAssetSync(PackagesName.GameData, "NPCCar")).GetComponent(); npcCar.SetSkinCar(skinCarID); npcCar.transform.localEulerAngles = new Vector3(0,90,0); npcCar.transform.position = pos; return npcCar; } /// /// 生成火车 /// public void GenerateTrain(LevelConfig levelConfig) { PutCar(); int rLan = Random.Range(0, 2); Train train = CachePoolManager.Instance.Take(YooAssetManager.Instance.LoadAssetSync(PackagesName.GameData, "Train")).GetComponent(); train.transform.position = generatePoints[rLan].transform.position; train.SetDirection(ProbabilityManager.Instance.GetPercent(50) ? E_DirectionType.Left : E_DirectionType.Right); trains.Add(train); GenerateRoundNPCCar(levelConfig, generatePoints[rLan == 0 ? 1 : 0]); } /// /// 生成一轮NPC车 /// private void GenerateRoundNPCCar(LevelConfig levelConfig, Transform generatePoint) { List recordGeneratingDistance = new List(); for (int i = 0; i < generatingDistance.Count; i++) { recordGeneratingDistance.Add(generatingDistance[i]); } int number; if (Scenes.Instance.gameScene.GetSchedule() < levelConfig.End / 3) { number = 2; } else { number = GetCurrentLaneNumber() - Random.Range(levelConfig.MinEmptyLane, (levelConfig.MaxEmptyLane + 1)); } for (int i = 0; i < number; i++) { (Vector3, int) pos = GetEmptyLane(); NPCCar npcCar = CachePoolManager.Instance.Take(YooAssetManager.Instance.LoadAssetSync(PackagesName.GameData, "NPCCar")).GetComponent(); npcCar.transform.SetParent(npcCarNode); npcCar.transform.localEulerAngles = Vector3.zero; int rPos = recordGeneratingDistance[Random.Range(0, recordGeneratingDistance.Count)]; npcCar.transform.localPosition = new Vector3(pos.Item1.x, 0, generatePoint.transform.localPosition.z + rPos); recordGeneratingDistance.Remove(rPos); npcCar.SetData(pos.Item2, this); LaneData laneData = new LaneData(); laneData.index = pos.Item2; laneData.car = npcCar; occupationIndex.Add(laneData); npcCars.Add(npcCar); } RandomChangeLanes(levelConfig); occupationIndex.Clear(); } /// /// 同行变道 /// public void SideBySideChangeLanes(LevelConfig levelConfig) { int number = Random.Range(levelConfig.MinLaneChangingCar,levelConfig.MaxLaneChangingCar+1); if(number>= occupationIndex.Count) { number = occupationIndex.Count-1; } if(number==3) { if(occupationIndex.Find(s => s.index == minIndex) != null && occupationIndex.Find(s => s.index == maxIndex) != null&& occupationIndex.Find(s => s.index == minIndex+1) != null && occupationIndex.Find(s => s.index == maxIndex-1)!=null) { number--; } } if(number==2) { if(occupationIndex.Find(s=>s.index==minIndex)!=null&& occupationIndex.Find(s => s.index == maxIndex) != null) { number--; } } bool isLeft = false; bool isRight = false; bool leftCondition = false;//条件是否成立 bool rightCondition = false;//条件是否成立 int startIndex = 0; LaneData laneData = null; exclude = new List(); for (int i = 0; i < number; i++) { record = new List(); for (int j = 0; j < occupationIndex.Count; j++) { if (exclude.Find(s => s.index == occupationIndex[j].index) == null) { record.Add(occupationIndex[j].index); } } while (true) { int randomIndex = record[Random.Range(0, record.Count)]; laneData = occupationIndex.Find(s => s.index == randomIndex); startIndex = laneData.index; isLeft = startIndex - 1 >= minIndex && occupationIndex.Find(s => s.index == startIndex - 1) == null; isRight = startIndex + 1 <= maxIndex && occupationIndex.Find(s => s.index == startIndex + 1) == null; if (isLeft) { leftCondition = number - i != 1 && JustFindLeft(startIndex,startIndex - 1)&&!AgainstFindRight(startIndex, startIndex-1); } if (isRight) { rightCondition =number - i != 1 && JustFindRight(startIndex,startIndex + 1)&&!AgainstFindLeft(startIndex,startIndex + 1); } if (isLeft && !leftCondition || isRight && !rightCondition) { break; } else { record.Remove(startIndex); } } if (ProbabilityManager.Instance.GetPercent(50)) { if (isLeft && leftCondition) { laneData.index++; laneData.car.SetRightLeft(E_DirectionType.Right); } else if (isLeft && !rightCondition) { laneData.index--; laneData.car.SetRightLeft(E_DirectionType.Left); } else if (isLeft) { laneData.index--; laneData.car.SetRightLeft(E_DirectionType.Left); } if (isRight && rightCondition) { laneData.index--; laneData.car.SetRightLeft(E_DirectionType.Left); } else if (isRight && !leftCondition) { laneData.index++; laneData.car.SetRightLeft(E_DirectionType.Right); } else if (isRight) { laneData.index++; laneData.car.SetRightLeft(E_DirectionType.Right); } } else { if (isRight && rightCondition) { laneData.index--; laneData.car.SetRightLeft(E_DirectionType.Left); } else if (isRight && !leftCondition) { laneData.index++; laneData.car.SetRightLeft(E_DirectionType.Right); } else if (isRight) { laneData.index++; laneData.car.SetRightLeft(E_DirectionType.Right); } if (isLeft && leftCondition) { laneData.index++; laneData.car.SetRightLeft(E_DirectionType.Right); } else if (isLeft && !rightCondition) { laneData.index--; laneData.car.SetRightLeft(E_DirectionType.Left); } else if (isLeft) { laneData.index--; laneData.car.SetRightLeft(E_DirectionType.Left); } } exclude.Add(laneData); } exclude.Clear(); } /// /// 随机变道 /// public void RandomChangeLanes(LevelConfig levelConfig) { LaneData laneData = null; int number = Random.Range(levelConfig.MinLaneChangingCar, levelConfig.MaxLaneChangingCar + 1); if(number>occupationIndex.Count) { number = occupationIndex.Count; } record = new List(); for (int i = 0; i < occupationIndex.Count; i++) { record.Add(occupationIndex[i].index); } for (int i = 0; i < number; i++) { int randomIndex = record[Random.Range(0, record.Count)]; laneData = occupationIndex.Find(s => s.index == randomIndex); laneData.car.ISChangeLanes(); record.Remove(randomIndex); } } /// /// 正向查找左边车道是否占满 /// public bool JustFindLeft(int startIndex,int index) { int numbr = 0; bool isTrue = false; for (int i = 0; i < occupationIndex.Count; i++) { if (occupationIndex[i].index < index && occupationIndex[i].index!= startIndex) { numbr++; } } for (int i = 1; i <= numbr; i++) { if (occupationIndex.Find(s => s.index == (index-i)) != null&& index - i != startIndex) { isTrue = true; } else { isTrue = false; break; } } return isTrue; } /// /// 正向查找右边车道是否占满 /// public bool JustFindRight(int startIndex,int index) { int numbr = 0; bool isTrue = false; for (int i = 0; i < occupationIndex.Count; i++) { if (occupationIndex[i].index > index && occupationIndex[i].index!= startIndex) { numbr++; } } for (int i = 1; i <= numbr; i++) { if (occupationIndex.Find(s => s.index == (index + i)) != null&& index+i!=startIndex) { isTrue = true; } else { isTrue = false; break; } } return isTrue; } /// /// 反向查找左边车道是否占满 /// public bool AgainstFindLeft(int startIndex, int index) { int numbr = 0; bool isTrue = false; for (int i = 0; i < occupationIndex.Count; i++) { if (occupationIndex[i].index < index) { numbr++; } } for (int i = 1; i <= numbr; i++) { if (occupationIndex.Find(s => s.index == (index - i)) != null && index - i != startIndex) { isTrue = true; break; } else { isTrue = false; } } return isTrue; } /// /// 反向查找右边车道是否占满 /// public bool AgainstFindRight(int startIndex, int index) { int numbr = 0; bool isTrue = false; for (int i = 0; i < occupationIndex.Count; i++) { if (occupationIndex[i].index > index) { numbr++; } } for (int i = 1; i <= numbr; i++) { if (occupationIndex.Find(s => s.index == (index + i)) != null && index + i != startIndex) { isTrue = true; break; } else { isTrue = false; } } return isTrue; } } /// /// 每条车道数据 /// public class LaneData { /// /// 车道索引 /// public int index; /// /// 车道上生成的车 是null则是空车道 /// public NPCCar car; }