C# 如何在程序生成的副本中修复AI的寻路问题?

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

我目前正在和敌人的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开始,在运行时烘焙是可能的

文档有点参差不齐,但应该可以使用。这是一个相对较新的功能