Как исправить поиск пути для ИИ в процедурном сгенерированном подземелье? - PullRequest
0 голосов
/ 09 января 2019

В настоящее время я работаю над процедурным генератором подземелий 3D с вражескими ИИ. Как мне исправить поиск пути для вражеских ИИ в этой ситуации?

Невозможно испечь navmesh во время выполнения, и подземелье генерируется по-разному при каждом запуске. Подземелье состоит из сборных узлов, комнат и коридоров. Враги не могут двигаться без навигационной сетки. Я создал AI с помощью дерева поведения панды. Предполагается, что один ИИ следует по пути, заданному путевыми точками, и бегает, когда видит игрока. Другой ИИ бродит по карте в поисках игрока.

Подземелье генерируется в классе, показанном ниже. У меня есть другой класс, который рисует Gizmos в дверях каждого сборного дома, и другой класс, который возвращает 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);
}
}

ИИ прекрасно работает как на карте, которая не генерируется случайным образом, так и запекается. Как я могу исправить поиск пути для ИИ в этом процедурном сгенерированном подземелье?

1 Ответ

0 голосов
/ 10 января 2019

Я вполне уверен, что выпекать можно во время выполнения с 2017.1 года и далее

https://unity3d.com/learn/tutorials/topics/navigation/baking-navmesh-runtime

Документация немного пятнистая, но она должна работать. Это относительно новая функция.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...