Скрипт работает правильно на одном игровом объекте, но не на другом - PullRequest
0 голосов
/ 10 июня 2018

У меня очень странная проблема.

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

Мне пришлось заменить модель для этого ИИ (раньше была капсулой), поэтому я сделал это, скопировал почти все компоненты, отрегулировал несколько параметров, таких как высота агента и т. Д., И запустил его.

ИИ капсулывыполняет свою работу должным образом, но ИИ с правильной моделью явно не делает.
После отладки я обнаружил, что Список назначений для моделируемого ИИ состоит из Vector3.zero, в то время как ИИ капсулы имеет правильныйvector3s в списке пунктов назначения.

Вот мой сценарий назначения AI:

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

public class AIMovement : MonoBehaviour
{

private NavMeshAgent _navMeshAgent;                         //reference to the navmesh agent
private MapController _mapControllerScript;                 //reference to the map controller script to access waypoints
private List<Vector3> _wayPoints = new List<Vector3>();
private Vector3 _destination;

// Use this for initialization
void Start()
{
    _mapControllerScript = GameObject.Find("Map_01").GetComponent<MapController>();
    SetWayPointLocations();
    _navMeshAgent = this.GetComponent<NavMeshAgent>();

    Debug.Log(_mapControllerScript.ToString());
    Debug.Log(_mapControllerScript.HealthPickUpPositions.ToString());
    Debug.Log(_navMeshAgent);
    Debug.Log(_wayPoints);
    foreach (Vector3 waypoint in _wayPoints)
    {
        Debug.Log(waypoint);
    }
}

// Update is called once per frame
void Update()
{
    MoveAroundMap();
}

void MoveAroundMap()
{
    if (_navMeshAgent.transform.position.x == _destination.x &&
        _navMeshAgent.transform.position.z == _destination.z
        || _destination == new Vector3(0, 0, 0)
        )
    {
        Debug.Log("Acquiring new position");
        _destination = _wayPoints[Random.Range(0, _wayPoints.Count-1)];
    }

    _navMeshAgent.SetDestination(_destination);
}

void SetWayPointLocations()
{
    foreach (Vector3 waypoint in _mapControllerScript.HealthPickUpPositions)
    {
        _wayPoints.Add(waypoint);
    }
    foreach (Vector3 waypoint in _mapControllerScript.AmmoPickUpPositions)
    {
        _wayPoints.Add(waypoint);
    }
}
}

Вот консоль: вы можете ясно видеть, что координаты капсульного AI верны, а координаты сломанного ИИ (0, 0, 0) .

Console

Вот окно иерархии : Капсулаэто рабочий AI, Character_Piccolo нерабочий.

Hierarchy

Вот инспектор капсулы, рабочийAI .

Inspector_Capsule

Вот инспектор модели, сломанный AI .

Inspector_Broken_Model

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

Заранее спасибо!

1 Ответ

0 голосов
/ 11 июня 2018

Проблема - а также ее решение - отсутствуют в вашем сценарии AIMovement или в каких-либо изменениях, которые вы выполняли при переходе с капсулы на новую модель, даже в сценарии и компоненты, которые вы указали в вопросе.,Проблема заключается в тонкости вашего MapController класса, который уже был там все время (даже до ваших изменений), и тот факт, что вы не сталкивались с этой ошибкой раньше, является вопросом случайности.

Когда выв комментариях вы устанавливаете HealthPickUpPositions и AmmoPickUpPositions свойства своего MapController класса в его методе Start().И вы читаете значения этих свойств в методе Start() вашего класса компонентов.Дело в том, что сообщение Start запускается, как только gameObject устанавливается на загруженной сцене, но порядок запуска объектов не зависит от логики вашей игры (это зависит от иерархии сцены, префабов, объектаномер экземпляра и прочее, что угодно ...) и следует считать случайными .

В вашем конкретном случае Start() вашего AIMovement вызывается до Start() of MapController, то есть перед правильными значениями устанавливаемых свойств - следовательно, все, что вы читаете, это нулевые векторы (значения по умолчанию).

Из-за этого у единицы есть похожее сообщение с именем Awake()на игровых объектах.Вы также не знаете порядок, в котором объекты будут вызываться, но вы можете быть уверены, что любое сообщение Start() будет отправлено только после того, как все сообщения Awake() уже были отправлены.Подробнее об этом здесь , здесь , здесь и здесь .

Решение :Поместите всю внутреннюю логику инициализации ваших классов в метод Awake;и все соединения с другими игровыми объектами (которые предполагают, что они инициализированы) в методе Start.

...