脚本在一个游戏对象上正常工作,但在另一个游戏对象上没有

时间:2018-06-10 15:48:48

标签: c# unity3d coordinates agent navmesh

我有一个非常奇怪的问题。

我使用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)

Console

这里是层次结构窗口:Capsule是工作AI,Character_Piccolo是非工作。

Hierarchy

这里是Capsule的检查员工作AI

Inspector_Capsule

此处是模型的检查员损坏的AI

Inspector_Broken_Model

很抱歉这么长,但我想确保你们有所有必要的信息。

提前致谢!

1 个答案:

答案 0 :(得分:2)

问题 - 以及解决方案 - 不在您的AIMovement脚本中,也不在您从胶囊更换到新模型时执行的任何编辑中,甚至不在您提供的任何脚本和组件中这个问题。问题是你MapController课程中一直存在的微妙之处(甚至在你的修改之前),以及你之前没有遇到过这个错误的事实是一个随意的问题。

正如您在评论中所说,您在HealthPickUpPositions方法中设置了AmmoPickUpPositions类的MapControllerStart()属性。并且您正在组件类的Start()方法中读取这些属性的值。问题是:一旦在加载的场景上设置了gameObject,就会运行Start消息,但该对象的开始顺序不依赖于您的游戏逻辑(它取决于场景层次结构,预制件,对象实例编号和其他东西,无论......)和应该被认为是随机的

在您的具体情况下,Start() AIMovement的{​​{1}}在Start() MapController之前被调用,即在设置属性的正确值之前 - 因此,你所读到的都是零向量(默认值)。

因此,unity在gameObjects上有一条名为Awake()的类似消息。您也不知道对象将被唤醒的顺序,但您可以确保只有在已经发送了所有Start()消息后才会发送任何Awake()消息。有关此herehereherehere的更多信息。

解决方案:将您的类的所有内部初始化逻辑放在Awake方法中;以及在Start方法上与其他游戏对象(假设它们已初始化)的所有连接。