Я создаю патрулирующий ИИ, который агрегирует игрока и следует за ним в Unity 3D. - PullRequest
0 голосов
/ 02 мая 2019

У меня проблемы с запуском этого метода. Он работает на 1 кадр, они отключаются. У меня проблемы с выработкой логики, чтобы он работал. Да, враг обнаруживает, находится ли игрок в поле зрения, и останавливается, когда сталкивается со стенами, он также прекращает обнаруживать игрока, когда он покидает поле зрения.

Я попытался изменить операторы if, но в целом очень важно, чтобы код выполнялся на основе проигрывателя, существующего в коллайдере FOV. Эта проблема довольно специфична, поэтому я не знаю, что делать.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

[RequireComponent(typeof(Animator))]
[RequireComponent(typeof(NavMeshAgent))]
[RequireComponent(typeof(AudioSource))]
public class EnemyAI : MonoBehaviour
{
    public float patrolSpeed, chaseSpeed, chaseWaitTime, patrolWaitTime, castRadius;
    public Transform[] wayPoints, wayPOI;
    public Transform player;
    public Animation flinch, die;
    public AudioClip grunt, callOut, death;
    public LayerMask mask;
    public PlayerCheck check;
    private float chaseTimer, patrolTimer, wanderTimer;
    private int destIndex, destInit, destStart, health;
    private bool playerIn;
    protected string aggro, resting, warned, sawPlayer;
    protected bool patroling;
    public bool aggress;
    private NavMeshAgent agent;
    private Transform playerLP;
    private Vector3 startPos;
    private Animator anim;
    private AudioSource aud;
    MeshCollider fieldOfView;
    void Awake()
    {
        //patroling = true;
        startPos = transform.position;
        destInit = destIndex;
        agent = GetComponent<NavMeshAgent>();
        agent.autoRepath = true;
        agent.autoBraking = true;
        fieldOfView = transform.GetChild(0).GetComponent<MeshCollider>();
        if (fieldOfView == null)
        {
            Debug.LogError("The first object MUST be FOV, otherwise the script will not work correctly. 1");
        }
        check = GameObject.FindObjectOfType<PlayerCheck>();
        anim = GetComponent<Animator>();
    }

    void FixedUpdate()
    {
        if (check == null)
        {
            check = GameObject.FindObjectOfType<PlayerCheck>();
        }

        playerIn = check.playerIn;
        RaycastHit hit;

        if (Physics.Linecast(transform.position, player.position, out hit, ~mask))
        {
            if (!playerIn)
            {
                Debug.DrawLine(transform.position, hit.point, Color.red);
            }
            else if (hit.collider.gameObject != null)
            {
                if (!hit.collider.CompareTag("Player"))
                {
                    Debug.DrawLine(transform.position, hit.point, Color.blue);
                    return;
                }
                else
                {
                    Debug.DrawLine(transform.position, hit.point, Color.green);
                    aggress = true;
                }
            }
        }

        if (aggress)
        {
            Aggro(sawPlayer);
        }

        if (patroling)
        {
            GoToNext();
        }
    }

    void GoToNext()
    {
        patroling = true;
        aggress = false;
        if (wayPoints.Length == 0)
            return;

        if (playerIn)
            return;

        if (agent.remainingDistance < .7f)
        {
            agent.SetDestination(wayPoints[destIndex].position);
            destIndex = (destIndex + 1) % wayPoints.Length;
        }
    }

    void Aggro(string condition)
    {
        if (condition == sawPlayer)
        {
            Chase(player);
        }
    }

    void Chase(Transform transform)
    {
        patroling = false;
        if (playerIn)
        {
            agent.SetDestination(transform.position);
            print("Chasing");
        }
        else
        {
            **Wander(sawPlayer, 15);**
            print("Wander, please");
        }
    }

    **void Wander(string condition, float time)**
    {
        patroling = false;
        print(time);
        wanderTimer += Time.deltaTime;

        print("Wandering");
        //this is where I'm having the most trouble, it will print wandering for 1 //frame then stop and go back to patroling
        //once the player leaves the fov. I'm trying to figure out where the method //stops and why.

        if (condition == sawPlayer)
        {
            if (wanderTimer >= time)
            {
                wanderTimer = 0;
                if (!agent.pathPending && agent.remainingDistance < .5f)
                {
                    GoToNext();
                }
            }
            else
            {
                Vector3 vec;
                vec = new Vector3(Random.Range(agent.destination.x - 10, agent.destination.x), Random.Range(agent.destination.y - 10, agent.destination.y), Random.Range(agent.destination.z - 10, agent.destination.z));
                agent.destination = transform.InverseTransformDirection(vec);

                if (agent.remainingDistance < .3f || wanderTimer > time)
                {
                    GoToNext();
                }
            }
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...