408 lines
13 KiB
C#
408 lines
13 KiB
C#
using Config.config;
|
|
using Sirenix.OdinInspector;
|
|
using System.Collections.Generic;
|
|
using Unity.VisualScripting;
|
|
using UnityEngine;
|
|
using UnityEngine.Rendering;
|
|
|
|
/// <summary>
|
|
/// 路段_生成NPC车辆
|
|
/// </summary>
|
|
public partial class SectionRoad
|
|
{
|
|
/// <summary>
|
|
/// 占用车道列表
|
|
/// </summary>
|
|
public List<LaneData> occupationIndex = new List<LaneData>();
|
|
|
|
/// <summary>
|
|
/// 排除已换的车辆
|
|
/// </summary>
|
|
private List<LaneData> exclude;
|
|
|
|
/// <summary>
|
|
/// 记录变道车辆
|
|
/// </summary>
|
|
private List<int> record;
|
|
|
|
/// <summary>
|
|
/// 生成NPC车
|
|
/// </summary>
|
|
public void GenerateNPCCar(List<int> ints, LevelConfig levelConfig)
|
|
{
|
|
PutCar();
|
|
for (int i = 0; i < ints.Count; i++)
|
|
{
|
|
GenerateRoundNPCCar(levelConfig, generatePoints[ints[i]]);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 指定位置生成车
|
|
/// </summary>
|
|
/// <param name="index"></param>
|
|
public NPCCar GenerateNPCCar(Vector3 pos,string skinCarID)
|
|
{
|
|
NPCCar npcCar =CachePoolManager.Instance.Take(YooAssetManager.Instance.LoadAssetSync<GameObject>(PackagesName.GameData, "NPCCar")).GetComponent<NPCCar>();
|
|
npcCar.SetSkinCar(skinCarID);
|
|
npcCar.transform.localEulerAngles = new Vector3(0,90,0);
|
|
npcCar.transform.position = pos;
|
|
return npcCar;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 生成火车
|
|
/// </summary>
|
|
public void GenerateTrain(LevelConfig levelConfig)
|
|
{
|
|
PutCar();
|
|
int rLan = Random.Range(0, 2);
|
|
Train train = CachePoolManager.Instance.Take(YooAssetManager.Instance.LoadAssetSync<GameObject>(PackagesName.GameData, "Train")).GetComponent<Train>();
|
|
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]);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 生成一轮NPC车
|
|
/// </summary>
|
|
private void GenerateRoundNPCCar(LevelConfig levelConfig, Transform generatePoint)
|
|
{
|
|
List<int> recordGeneratingDistance = new List<int>();
|
|
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<GameObject>(PackagesName.GameData, "NPCCar")).GetComponent<NPCCar>();
|
|
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();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 同行变道
|
|
/// </summary>
|
|
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<LaneData>();
|
|
|
|
for (int i = 0; i < number; i++)
|
|
{
|
|
record = new List<int>();
|
|
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();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 随机变道
|
|
/// </summary>
|
|
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<int>();
|
|
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);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 正向查找左边车道是否占满
|
|
/// </summary>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 正向查找右边车道是否占满
|
|
/// </summary>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 反向查找左边车道是否占满
|
|
/// </summary>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 反向查找右边车道是否占满
|
|
/// </summary>
|
|
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;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 每条车道数据
|
|
/// </summary>
|
|
public class LaneData
|
|
{
|
|
/// <summary>
|
|
/// 车道索引
|
|
/// </summary>
|
|
public int index;
|
|
|
|
/// <summary>
|
|
/// 车道上生成的车 是null则是空车道
|
|
/// </summary>
|
|
public NPCCar car;
|
|
}
|