Почему один из агентов navmesh не движется к следующей точке маршрута? - PullRequest
0 голосов
/ 10 мая 2019

В этом примере есть два агента navmesh. Один из них движется между путевыми точками. Второй достигает первой путевой точки, а затем останавливается и никогда не продолжает.

Я использую этот скрипт для генерации агентов navmesh и путевых точек:

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

public class InstantiateObjects : MonoBehaviour
{
    public GameObject prefab;
    public Terrain terrain;
    public float yOffset = 0.5f;
    public int objectsAmount;
    public bool parent = true;
    public bool randomScale = false;
    public string tag;
    public string name;

    public Vector3 RandScaleMin;
    public Vector3 RandScaleMax;

    private float terrainWidth;
    private float terrainLength;
    private float xTerrainPos;
    private float zTerrainPos;
    private GameObject clonedObject;
    private ObjectPool objectPool;

    public void Start()
    {
        //Get terrain size
        terrainWidth = terrain.terrainData.size.x;
        terrainLength = terrain.terrainData.size.z;

        //Get terrain position
        xTerrainPos = terrain.transform.position.x;
        zTerrainPos = terrain.transform.position.z;

        generateObjectOnTerrain();
    }

    public void Update()
    {

    }

    public void ReleaseObjects()
    {
        GameObject[] allobj = GameObject.FindGameObjectsWithTag(tag);
        for (var i = 0; i < allobj.Length; i++)
        {
            objectPool.ReturnInstance(allobj[i]);
            allobj[i].hideFlags = HideFlags.HideInHierarchy;
        }
        generateObjectOnTerrain();
    }

    public void generateObjectOnTerrain()
    {
        objectPool = new ObjectPool(prefab, objectsAmount);

        for (int i = 0; i < objectsAmount; i++)
        {
            //Generate random x,z,y position on the terrain
            float randX = UnityEngine.Random.Range(xTerrainPos, xTerrainPos + terrainWidth);
            float randZ = UnityEngine.Random.Range(zTerrainPos, zTerrainPos + terrainLength);

            float yVal = Terrain.activeTerrain.SampleHeight(new Vector3(randX, 0, randZ));

            var randScaleX = Random.Range(RandScaleMin.x, RandScaleMax.x);
            var randScaleY = Random.Range(RandScaleMin.y, RandScaleMax.y);
            var randScaleZ = Random.Range(RandScaleMin.z, RandScaleMax.z);
            var randVector3 = new Vector3(randScaleX, randScaleY, randScaleZ);

            //Apply Offset if needed
            yVal = yVal + yOffset;

            clonedObject = objectPool.GetInstance();

            if (randomScale == true)
                clonedObject.transform.localScale = randVector3;//new Vector3(randScaleX, randScaleY, randScaleZ);

            if (parent)
            {
                GameObject parent = GameObject.Find(name);
                clonedObject.transform.parent = parent.transform;
            }

            clonedObject.tag = tag;
            clonedObject.transform.position = new Vector3(randX, yVal, randZ);
        }
    }
}

И к каждому агенту navmesh я прилагаю этот скрипт:

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

public class AgentControl : MonoBehaviour
{
    public List<Transform> points = new List<Transform>();
    public bool isInMeeting = false;
    public float threshold = 3f;
    public float strength = 5f;

    private float speed;
    private int destPoint = 0;
    private NavMeshAgent agent;
    private NavMeshAgent[] agents;

    void Start()
    {
        agents = GameObject.FindObjectsOfType<NavMeshAgent>();

        agent = GetComponent<NavMeshAgent>();
        var agentsDestionations = GameObject.FindGameObjectsWithTag("Waypoint");

        for (int i = 0; i < agentsDestionations.Length; i++)
        {
            points.Add(agentsDestionations[i].transform);
        }
        // Disabling auto-braking allows for continuous movement
        // between points (ie, the agent doesn't slow down as it
        // approaches a destination point).
        agent.autoBraking = true;
        agent.speed = Random.Range(10, 50);
        speed = agent.speed;

        GotoNextPoint();
    }

    void GotoNextPoint()
    {
        // Returns if no points have been set up
        if (points.Count == 0)
            return;

        // Set the agent to go to the currently selected destination.
        agent.destination = points[destPoint].position;

        // Choose the next point in the array as the destination,
        // cycling to the start if necessary.
        destPoint = (destPoint + 1) % points.Count;
    }


    void Update()
    {
        float dist = Vector3.Distance(agent.transform.position, agents[1].transform.position);
        if (dist < 5)
        {
            isInMeeting = true;
            agents[1].GetComponent<AgentControl>().isInMeeting = true;
            StartCoroutine(Meeting(agents[1]));
        }

        //Meeting();
        // Choose the next destination point when the agent gets
        // close to the current one.
        if (!agent.pathPending && agent.remainingDistance < 2f)
        {
            if (isInMeeting == false)
                GotoNextPoint();
        }
    }

    private void Meeting()
    {

        //GameObject randomAgent = agents[Random.Range(0, agents.Length)];
        /*if (Vector3.Distance(agent.transform.position, agents[1].transform.position) <= threshold)
        {
            isInMeeting = true;
            StartCoroutine(Meeting(agents[1]));
        }*/

    }

    IEnumerator Meeting(NavMeshAgent Agent)
    {
        var targetRotation = Quaternion.LookRotation(Agent.transform.position - transform.position);
        var str = Mathf.Min(strength * Time.deltaTime, 1);
        transform.rotation = Quaternion.Lerp(transform.rotation, targetRotation, str);

        yield return new WaitForSeconds(10);
        isInMeeting = false;
    }
}

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

Это скриншот Иерархии во время игры, показывающий скрипт Инстанции Агентов в инспекторе:

* +1012 *Instantiate Agents Inspector

На этом снимке экрана показан Инспектор путевых точек:

Instantiate Waypoints Inspector

Последний снимок экрана, на котором показан инспектор сценариев управления агентом:

Agent Control Inspector* * 1030

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

Я хочу, чтобы они оба патрулировали между всеми путевыми точками.

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