C# 如何在程序生成的副本中修复AI的寻路问题?
我目前正在和敌人的AI一起开发3D程序地下城生成器。 在这种情况下,我如何修复敌人AI的路径查找 在运行时烘焙navmesh是不可能的,而且每次运行时生成的地下城都不同。地下城由交叉口、房间和走廊的预制件构成。 没有导航网,敌人无法移动。我用熊猫行为树创建了人工智能。一个AI应该沿着一条设定了航路点的路径,当它看到玩家时,它会四处跑动。另一个人工智能在地图上四处寻找玩家 地下城是在如下所示的类中生成的。 我还有一个类在每个预制件的门口绘制Gizmo,还有一个类返回“ModuleConnector”C# 如何在程序生成的副本中修复AI的寻路问题?,c#,unity3d,artificial-intelligence,path-finding,procedural-generation,C#,Unity3d,Artificial Intelligence,Path Finding,Procedural Generation,我目前正在和敌人的AI一起开发3D程序地下城生成器。 在这种情况下,我如何修复敌人AI的路径查找 在运行时烘焙navmesh是不可能的,而且每次运行时生成的地下城都不同。地下城由交叉口、房间和走廊的预制件构成。 没有导航网,敌人无法移动。我用熊猫行为树创建了人工智能。一个AI应该沿着一条设定了航路点的路径,当它看到玩家时,它会四处跑动。另一个人工智能在地图上四处寻找玩家 地下城是在如下所示的类中生成的。 我还有一个类在每个预制件的门口绘制Gizmo,还有一个类返回“ModuleConnector
public class ModularWorldGenerator : MonoBehaviour {
public Module[] Modules;
public Module StartModule;
public int Iterations = 5;
public void Start() {
var startModule = (Module) Instantiate(StartModule, transform.position, transform.rotation);
var pendingExits = new List<ModuleConnector>(startModule.GetExits());
for (int iteration = 0; iteration < Iterations; iteration++) {
var newExits = new List<ModuleConnector>();
foreach (var pendingExit in pendingExits) {
var newTag = GetRandom(pendingExit.Tags);
var newModulePrefab = GetRandomWithTag(Modules, newTag);
var newModule = (Module) Instantiate(newModulePrefab);
var newModuleExits = newModule.GetExits();
var exitToMatch = newModuleExits.FirstOrDefault(x => x.IsDefault) ?? GetRandom(newModuleExits);
MatchExits(pendingExit, exitToMatch);
newExits.AddRange(newModuleExits.Where(e => e != exitToMatch));
}
pendingExits = newExits;
}
}
private void MatchExits(ModuleConnector oldExit, ModuleConnector newExit) {
var newModule = newExit.transform.parent;
var forwardVectorToMatch = -oldExit.transform.forward;
var correctiveRotation = Azimuth(forwardVectorToMatch) - Azimuth(newExit.transform.forward);
newModule.RotateAround(newExit.transform.position, Vector3.up, correctiveRotation);
var correctiveTranslation = oldExit.transform.position - newExit.transform.position;
newModule.transform.position += correctiveTranslation;
}
private static TItem GetRandom<TItem>(TItem[] array) {
return array[Random.Range(0, array.Length)];
}
private static Module GetRandomWithTag(IEnumerable<Module> modules, string tagToMatch) {
var matchingModules = modules.Where(m => m.Tags.Contains(tagToMatch)).ToArray();
return GetRandom(matchingModules);
}
private static float Azimuth(Vector3 vector) {
return Vector3.Angle(Vector3.forward, vector) * Mathf.Sign(vector.x);
}
}
公共类ModularWorldGenerator:MonoBehavior{
公共模块[]模块;
公共模块StartModule;
公共整数迭代次数=5;
公开作废开始(){
var startModule=(模块)实例化(startModule,transform.position,transform.rotation);
var pendingExits=新列表(startModule.GetExits());
for(int iteration=0;iterationx.IsDefault)??GetRandom(newModuleExits);
匹配出口(pendingExit、exitToMatch);
newExits.AddRange(newModuleExits.Where(e=>e!=exitToMatch));
}
pendingExits=新出口;
}
}
私有无效匹配出口(ModuleConnect或oldExit、ModuleConnect或newExit){
var newModule=newExit.transform.parent;
var forwardVectorToMatch=-oldExit.transform.forward;
var correctiveRotation=方位角(ForwardVectorMatch)-方位角(newExit.transform.forward);
newModule.RotateAround(newExit.transform.position,Vector3.up,correctiveRotation);
var correctiveTranslation=oldExit.transform.position-newExit.transform.position;
newModule.transform.position+=正确的平移;
}
私有静态TItem GetRandom(TItem[]数组){
返回数组[随机.范围(0,数组.长度)];
}
私有静态模块GetRandomWithTag(IEnumerable模块、字符串标记匹配){
var matchingModules=modules.Where(m=>m.Tags.Contains(tagToMatch)).ToArray();
返回GetRandom(匹配模块);
}
专用静态浮动方位角(矢量3矢量){
返回向量3.角度(向量3.向前,向量)*数学符号(向量x);
}
}
人工智能的工作在一张不是随机生成的地图上都很好,并且已经烘焙了navmesh。
我如何修复人工智能在这个程序生成的地牢中的路径查找 我敢肯定,从2017.1开始,在运行时烘焙是可能的 文档有点参差不齐,但应该可以使用。这是一个相对较新的功能