c# - 脚本在一个游戏对象上正常工作,但在另一个游戏对象上不能正常工作
问题描述
我有一个非常奇怪的问题。
我使用 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。
抱歉,拖了这么久,但我想确保你们拥有所有需要的信息。
提前致谢!
解决方案
问题 - 以及解决方案 - 不在您的AIMovement
脚本中,也不在您从胶囊更改为新模型时所做的任何编辑中,甚至不在您在问题中提供的任何脚本和组件中。问题是您的MapController
课程中一直存在的微妙之处(甚至在您进行更改之前),而您之前没有遇到此错误的事实是偶然的。
正如您在评论中所说,您正在其方法中设置类HealthPickUpPositions
的AmmoPickUpPositions
属性。您正在组件类的方法中读取这些属性的值。问题是:一旦在加载的场景上设置了游戏对象,启动消息就会运行,但是对象启动的顺序不取决于您的游戏逻辑(它取决于场景层次结构、预制件、对象实例编号和其他内容,不管...),应该被认为是随机的。MapController
Start()
Start()
在您的特定情况下,Start()
您的 of在ofAIMovement
之前被调用,即在设置属性的正确值之前 - 因此,您读取的所有内容都是零向量(默认值)。Start()
MapController
因此,unityAwake()
在 gameObjects 上也有类似的消息。您也不知道唤醒对象的顺序,但您可以确保只有在所有消息都已发送Start()
后才会发送任何消息。Awake()
更多关于这里、这里、这里和这里的信息。
解决方案:将类的所有内部初始化逻辑放在 Awake 方法中;以及 Start 方法上与其他游戏对象的所有连接(假设它们已初始化)。
推荐阅读
- unity3d - 有什么方法可以阻止 Visual Studio 在新函数上添加“抛出新的 NotImplementedException”?导致命名空间与 Unity 冲突
- excel - 日历年的付款发票跟踪
- java - Guice volatile 注入属性之一
- numpy - 总结字典中的值
- javascript - JavaScript,在新选项卡中打开编码为 Base64 的 pdf,无需在 Google-Chrome 中下载
- javascript - 如何将下一个文本区域聚焦在按钮单击上
- react-native - ActivityIndicator 抛出类型错误 undefined is not an object
- php - 如果用户在 .htaccess 文件的 codeigniter 中输入 abc.com,如何将页面重定向到 www.abc.com
- android - 如何将当前交通数据绘制到谷歌地图上由谷歌方向 API 绘制的特定折线上
- swift - 如何在使用 URLSession 的异步 api 调用中查找哪个响应属于哪个请求