我有一个非常奇怪的问题。
我使用navmesh工具和自定义脚本创建了一个AI,一旦到达旧目的地,该脚本就会一直为navmesh代理分配新目的地。
我不得不替换这个AI的模型(之前是一个胶囊),所以我这样做了,复制了几乎所有组件,调整了一些参数,如代理高度等,然后运行它。
胶囊AI正常工作,但具有正确型号的AI显然不会 调试后,我发现建模AI的目的地列表包含Vector3.zero,而胶囊AI在目的地列表中有正确的vector3。
这是我的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的坐标是正确的,而破坏的AI的坐标是(0,0,0)。
这里是层次结构窗口:Capsule是工作AI,Character_Piccolo是非工作。
这里是Capsule的检查员,工作AI 。
此处是模型的检查员,损坏的AI 。
很抱歉这么长,但我想确保你们有所有必要的信息。
提前致谢!
答案 0 :(得分:2)
问题 - 以及解决方案 - 不在您的AIMovement
脚本中,也不在您从胶囊更换到新模型时执行的任何编辑中,甚至不在您提供的任何脚本和组件中这个问题。问题是你MapController
课程中一直存在的微妙之处(甚至在你的修改之前),以及你之前没有遇到过这个错误的事实是一个随意的问题。
正如您在评论中所说,您在HealthPickUpPositions
方法中设置了AmmoPickUpPositions
类的MapController
和Start()
属性。并且您正在组件类的Start()
方法中读取这些属性的值。问题是:一旦在加载的场景上设置了gameObject,就会运行Start消息,但该对象的开始顺序不依赖于您的游戏逻辑(它取决于场景层次结构,预制件,对象实例编号和其他东西,无论......)和应该被认为是随机的。
在您的具体情况下,Start()
AIMovement
的{{1}}在Start()
MapController
之前被调用,即在设置属性的正确值之前 - 因此,你所读到的都是零向量(默认值)。
因此,unity在gameObjects上有一条名为Awake()
的类似消息。您也不知道对象将被唤醒的顺序,但您可以确保只有在已经发送了所有Start()
消息后才会发送任何Awake()
消息。有关此here,here,here和here的更多信息。
解决方案:将您的类的所有内部初始化逻辑放在Awake方法中;以及在Start方法上与其他游戏对象(假设它们已初始化)的所有连接。