代码之家  ›  专栏  ›  技术社区  ›  Thrindil

脚本可以在一个游戏对象上正常工作,但不能在另一个游戏对象上正常工作

  •  0
  • Thrindil  · 技术社区  · 6 年前

    我有一个很奇怪的问题。

    我使用navmesh工具和自定义脚本创建了一个a i,该脚本在到达旧的目的地后,将一个新的目的地分配给navmesh代理。

    我不得不替换这个AI模型(以前是一个胶囊),所以我这样做,复制了几乎所有的组件,调整了一些像代理高度等参数,并运行它。

    胶囊式人工智能做得很好,但模型正确的人工智能显然做不到。
    在调试之后,我发现建模人工智能的目标列表包含if vector3.zero,而胶囊人工智能的目标列表中包含正确的vector3。

    这是我的人工智能目标脚本:

    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

    这里是 层次结构窗口 :胶囊是工作的人工智能,字符是非工作的短笛。

    Hierarchy

    这里是 检查员 在太空舱里, 工作人工智能 .

    Inspector_Capsule

    这里是 检查员 模型中的 破碎的人工智能 .

    Inspector_Broken_Model

    抱歉耽搁了这么久,但我想确定你们有所有需要的信息。

    提前谢谢!

    1 回复  |  直到 6 年前
        1
  •  2
  •   Rodrigo Rodrigues    6 年前

    问题和解决方法不在你的 AIMovement 脚本,或者在从胶囊更改为新模型时所做的任何编辑中,甚至在问题中提供的任何脚本和组件中都不需要。你的问题很微妙 MapController 类已经一直在那里(甚至在你的改变之前),并且事实上你以前没有经历过这个错误是一个偶然的问题。

    正如你在评论中所说,你正在设置 HealthPickUpPositions AmmoPickUpPositions 你的财产 地图控制器 类中 Start() 方法。你正在阅读 START() 组件类的方法。问题是:一旦在加载的场景上设置了gameobject,开始消息就会运行,但是 对象开始的顺序 不依赖于你的游戏逻辑(它取决于场景层次结构、预设、对象实例号和其他东西,不管怎样……) 应该被认为是随机的 .

    在你的具体案例中, 小精灵 你的 瞄准 START() 属于 地图控制器 ,也就是说,在设置属性的正确值之前-因此,您所读的全部是零向量(默认值)。

    因此,unity有一个类似的消息名为 Awake() 在游戏对象上。你也不知道物体会被唤醒的顺序,但是你可以保证任何物体都会被唤醒。 小精灵 只有在 唤醒() 已发送邮件。更多关于这个 here , here , here here .

    解决方案 :将类的所有内部初始化逻辑置于唤醒方法中;将与其他游戏对象(假设它们已初始化)的所有连接置于启动方法中。