Триггеры и действия для AI существа - PullRequest
1 голос
/ 15 мая 2019

Несмотря на то, что мой ИИ существа работает (по большей части), я чувствую, что способ его настройки ужасно неэффективен и, вероятно, совершает некоторые грехи программирования.Я хочу переписать его, чтобы он был более чистым, эффективным и простым в обслуживании, но я не совсем уверен, с чего начать.

В моем AI существа у меня есть список триггеров, таких как OnSpawn, OnDeath или OnCollisionEnter.В каждом триггере есть список действий, таких как «Разыграть заклинание» или «Воспроизвести анимацию».Когда условия триггера выполнены, его список действий обрабатывается, чтобы проверить, не находится ли он уже в нашем списке обработки, добавляет его, а затем воспроизводит связанные с ним действия.Когда условия триггера не выполняются, список действий удаляется из этого списка процессов и аналогичным образом обрабатывается с помощью некоторых функций удаления для очистки поведения.

Некоторый код, который я упростил:

    void Update()
    {
        if (canAct && !dead)
        {
            CheckTriggers();
            PlayAllActions();
       }
     }


   private void CheckTriggers()
    {
        for (int i = 0; i < actions.Length; i++)
        {
            switch (actions[i].trigger)
            {
                case ActionTrigger.Trigger.OnCollisionEnter:
                    if (isColliding)
                        AddActionList(actions[i].actionSetList);
                    else
                        RemoveActionList(actions[i].actionSetList);
                    break;

                case ActionTrigger.Trigger.UponBeingAttacked:
                    if (hasBeenAttacked)
                        AddActionList(actions[i].actionSetList);
                    break;
            }
        }
    }

    public void AddActionList(ActionSetList actionSetList)
    {
        bool containsItem = existingActionsList.Any(item => item == actionSetList);
        if (containsItem)
            return;

        existingActionsList.Add(actionSetList);
    }

    private void PlayAllActions()
    {
        if (existingActionsList.Count > 0)
            for (int i = 0; i < existingActionsList.Count; i++)
                ActionPlayEffect(existingActionsList[i]);
    }

    public void ActionPlayEffect(ActionSetList actionSetList)
    {
        for (int i = 0; i < actionSetList.Length; i++)
        {
            switch (actionSetList[i].type)
            {
                case ActionSet.Type.CastSpell:
                    if (spellRoutine == null && actionSetList[i].cooldownTimeRemaining <= 0)
                        spellRoutine = StartCoroutine(Cast(actionSetList[i]));
                    break;

                case ActionSet.Type.PlayAnim:
                    if (!isInActionPose)
                    {
                        animator.SetTrigger("ActionTrigger");
                        animator.SetInteger("Action", (int)actionSetList[i].animToPlay+1);
                        isInActionPose = true;
                    }
                    break;
            }
        }
    }

    public void RemoveActionList(ActionSetList actionSetList)
    {
        bool containsItem = existingActionsList.Any(item => item == actionSetList);
        if (containsItem)
        {
            ActionRemoveEffect(actionSetList);
            existingActionsList.Remove(actionSetList);
        }
    }

    public void ActionRemoveEffect(ActionSetList actionSetList)
    {
        for (int i = 0; i < actionSetList.Length; i++)
        {
            switch (actionSetList[i].type)
            {
                case ActionSet.Type.CastSpell:
                    CancelCast();
                    break;

                case ActionSet.Type.PlayAnim:
                    animator.SetTrigger("ActionTrigger");
                    animator.SetInteger("Action", 0);
                    isInActionPose = false;
                    break;
            }
        }
    }

Что я могу сделать для создания более эффективного ИИ существа?

1 Ответ

0 голосов
/ 15 мая 2019

Я бы, вероятно, написал аналогичную систему, используя делегаты .

Делегат можно в некоторой степени считать переменной, содержащей список методов.Если вы выполняете этот делегат, вы затем выполняете все методы, которые он содержит.

Это позволит вам добавлять методы, подобные этому, в список методов, которые вы затем вызываете при желании.

delegate void OnSpawn(GameObject gameObject); //Create delegate type
public OnSpawn onSpawn; //Create variable from delegate type

void SetUpStats(Gameobject gameObject){
    //Set hp, initialize spells
}

void SetUpAnimations(GameObject gameObject){
    //Initialize animations
}

void PlaySpawnSound(GameObject gameObject){
    //Play a spawn sound
}

void Start(){
    if (onSpawn == null) //Add content to delegate
    {
        onSpawn = new OnSpawn(SetUpStats); //You may be able to write onSpawn = SetUpStats; instead, for shorter code. But please test it.
        onSpawn += SetUpAnimations;
        onSpawn += PlaySpawnSound;
    }
}

void Spawn(){
    onSpawn(gameObject); 

    //Call delegate, invoking all methods stored in it. 
    //Note that they all receive the same input. In this case the gameObject.
    //You can give them any input you want, so long as you define it in the delegate type.
    //I chose a gameObject as you can get all components and more from it.
}

Дайте мне знать, если у вас есть какие-либо вопросы или вопросы, которые вас интересуют.

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