OvertakingLegend/Assets/Script/SectionRoad/SectionRoad_GenerateNPCCar.cs

408 lines
13 KiB
C#
Raw Permalink Normal View History

2025-03-24 03:08:22 +00:00
using Config.config;
using Sirenix.OdinInspector;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.Rendering;
/// <summary>
/// ·<><C2B7>_<EFBFBD><5F><EFBFBD><EFBFBD>NPC<50><43><EFBFBD><EFBFBD>
/// </summary>
public partial class SectionRoad
{
/// <summary>
/// ռ<>ó<EFBFBD><C3B3><EFBFBD><EFBFBD>б<EFBFBD>
/// </summary>
public List<LaneData> occupationIndex = new List<LaneData>();
/// <summary>
/// <20>ų<EFBFBD><C5B3>ѻ<EFBFBD><D1BB>ij<EFBFBD><C4B3><EFBFBD>
/// </summary>
private List<LaneData> exclude;
/// <summary>
/// <20><>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
private List<int> record;
/// <summary>
/// <20><><EFBFBD><EFBFBD>NPC<50><43>
/// </summary>
public void GenerateNPCCar(List<int> ints, LevelConfig levelConfig)
{
PutCar();
for (int i = 0; i < ints.Count; i++)
{
GenerateRoundNPCCar(levelConfig, generatePoints[ints[i]]);
}
}
/// <summary>
/// ָ<><D6B8>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD>ɳ<EFBFBD>
/// </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>
/// <20><><EFBFBD>ɻ<EFBFBD><C9BB><EFBFBD>
/// </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>
/// <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>NPC<50><43>
/// </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>
/// ͬ<>б<EFBFBD><D0B1><EFBFBD>
/// </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;//<2F><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>
bool rightCondition = false;//<2F><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>
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>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </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>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD><DFB3><EFBFBD><EFBFBD>Ƿ<EFBFBD>ռ<EFBFBD><D5BC>
/// </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>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ұ߳<D2B1><DFB3><EFBFBD><EFBFBD>Ƿ<EFBFBD>ռ<EFBFBD><D5BC>
/// </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>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD><DFB3><EFBFBD><EFBFBD>Ƿ<EFBFBD>ռ<EFBFBD><D5BC>
/// </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>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ұ߳<D2B1><DFB3><EFBFBD><EFBFBD>Ƿ<EFBFBD>ռ<EFBFBD><D5BC>
/// </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>
/// ÿ<><C3BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
public class LaneData
{
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
public int index;
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɵij<C9B5> <20><>null<6C><6C><EFBFBD>ǿճ<C7BF><D5B3><EFBFBD>
/// </summary>
public NPCCar car;
}