【问题标题】:Tracking a game object transform - Why using FindGameObjectWithTag doesn't work?跟踪游戏对象变换 - 为什么使用 FindGameObjectWithTag 不起作用?
【发布时间】:2015-07-14 12:05:55
【问题描述】:

我正在学习一个教程(确切地说是survival shooter),我正处于实现导航网格的阶段。他们原来的脚本是这样的:

 Transform _player;
 NavMeshAgent nav;

 void Start()
 {
     _player = GameObject.FindGameObjectWithTag("Player").transform;
     nav = GetComponent<NavMeshAgent>();
 }

 void Update()
 {
     nav.SetDestination(_player.position);     
 }

到目前为止没有什么特别的。我按下播放键,奇怪的是敌人(我现在场景中只有一个)只到达玩家的初始位置(0,0,0),而不是在玩家移动时跟随它。我意识到玩家的位置在_player 字段中没有更新,它保持在0,0,0

我尝试了一种不同的方法:我将玩家的游戏对象拖放到 UI 中的属性上(我首先将属性公开,然后将其更改为 GameObject)。在这种情况下,它可以完美运行:

 GameObject _player;
 NavMeshAgent nav;

 void Start()
 {
     //Player is not retrieved here as before, but it's passed assigning the GameObject to the property directly through the UI
     nav = GetComponent<NavMeshAgent>();
 }

 void Update()
 {
     nav.SetDestination(_player.transform.position);     
 }

在这个阶段我想知道:

FindGameObjectWithTag 方法是否会复制对象而不是返回对GameObject 的引用?为什么它在第一个实例中不起作用。顺便说一句,我使用 Unity 5。

【问题讨论】:

  • 我重新创建了这种情况,我相信 FindGameObjectWithTag() 在调用它时会返回对象的副本。阅读有关此方法的文档似乎可以确认这一点,因为没有提及参考。
  • 我脑子里唯一的想法是游戏对象当时没有激活,所以 FindGameObjectWithTag 不会检测到它。
  • 可能值得一试的是使用FindGameObjectsWithTag 并查看是否返回了多个东西。也许你得到的就像是不动的预制件或其他东西。
  • @UriPopov 你能把你读过的文档的链接发给我吗?我想我错过了:/
  • @GregLukosek 不,它处于活动状态,但我会仔细检查。虽然它是复制品的理论听起来很合理

标签: c# unity3d reference unity5 navmesh


【解决方案1】:

场景中可能有超过 1 个带有“玩家”标签的对象。我更改了您的代码以检测这种情况。

Transform _player;
NavMeshAgent nav;

void Start()
{
    GameObject[] playerObjects = GameObject.FindGameObjectsWithTag("Player");
    if(playerObjects.Length>1) 
    {
        Debug.LogError("You have multiple player objects in the scene!");
    }
    _player = playerObjects[0].transform;
    nav = GetComponent<NavMeshAgent>();
}

void Update()
{
    nav.SetDestination(_player.position);     
}

【讨论】:

    【解决方案2】:

    我发现可能存在很多不同的问题:

    所以这是你应该测试的:

    • 首先你应该尝试: GameObject.FindGameObjectWithTag("Player").GetComponent&lt;Transform&gt;();

    • 如果您的玩家游戏对象具有唯一名称,请尝试使用

    Transform playerTransform = GameObject.Find("MyPlayerName").transform

    • 如果还是不行,如果这个脚本分配给你的玩家,你可以使用this访问gameObject

    • 如果您的脚本未附加到您的玩家游戏对象,您可以将您的玩家游戏对象设置为脚本的公共属性。然后在编辑器中,抓取您的玩家游戏对象并将其放在您的类属性的正确大小写中。在这种情况下,您的声明应该是:

    public GameObject myPlayer;

    • 但是在测试任何这些方法之前,您应该通过在此编辑器中简单地使用您的玩家名称来测试问题是否来自GameObject.FindGameObjectWithTag。假设您的游戏对象玩家名称是 MyFantasticPlayer。然后试试这个:

      `GameObject myPlayer = GameObject.FindGameObjectWithTag("Player");
      if(myPlayer.name == "MyFantasticPlayer")
      {
         Debug.Log("Not problem with FindGameObjectWithTag");
      }else{
      Debug.Log("Problem");
      }`
      

    如果您的调试日志显示有问题,则可以尝试捕获异常。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多