【问题标题】:How to get Object tag having its position?如何让对象标签有它的位置?
【发布时间】:2018-10-19 12:30:09
【问题描述】:

我是 Unity 新手,一个问题是从我身上偷走了太多时间。

无论如何,我正在尝试从场景中获取对象标签,同时拥有它的 X 和 Z 位置。指定,我想通过获取围绕我的机器人的游戏对象标签来获取神经网络的输入。有没有像GetComponent<>() 这样的函数或者可以接受x,z 并返回标签的函数?

还有一个问题,我手动将emptyObject 放在每个空白空间中,这样我就可以得到一些回报。如果我删除这些“空块”并尝试在特定的 x、z 位置检查某些内容,会有问题吗?

【问题讨论】:

  • 我不知道,但您可以创建一个“触发器”,将对象添加到他检测到的区域,然后您可以检查这些对象的标签。

标签: c# unity3d components gameobject


【解决方案1】:

您可以使用Transform 搜索场景中的每个对象,然后查找搜索具有 x 和 z 位置的对象并返回标签。 Resources.FindObjectsOfTypeAllGameObject.FindObjectsOfType 函数可以做到这一点,但为了性能,使用 Scene.GetRootGameObjects 获取所有根对象,并使用 GetComponentsInChildren<Transform> 从每个根对象的子对象中获取所有子对象,并检查 x 和 z位置匹配。

使用它们,因为它们不返回数组,而只是填充一个列表。

找到场景中的所有对象

private List<GameObject> rootGameObjects = new List<GameObject>();
private List<Transform> childObjs = new List<Transform>();

private void GetAllRootObject()
{
    Scene activeScene = SceneManager.GetActiveScene();
    activeScene.GetRootGameObjects(rootGameObjects);
}

private void GetAllChildObjs()
{
    for (int i = 0; i < rootGameObjects.Count; ++i)
    {
        GameObject obj = rootGameObjects[i];

        //Get all child components attached to this GameObject
        obj.GetComponentsInChildren<Transform>(true, childObjs);
    }
}

寻找带有 x,z 位置的对象标签

bool xzEquals(Vector3 pos1, Vector3 pos2)
{
    return (Mathf.Approximately(pos1.x, pos2.x)
        && Mathf.Approximately(pos1.z, pos2.z));
}

string GetTagFromPos(float x, float z)
{
    Vector3 pos = new Vector3(x, 0, z);

    rootGameObjects.Clear();
    childObjs.Clear();

    GetAllRootObject();
    GetAllChildObjs();

    //Loop through all Objects
    for (int i = 0; i < childObjs.Count; i++)
        //check  if x and z matches then return tag
        if (xzEquals(childObjs[i].position, pos))
            return childObjs[i].tag;

    return null;
}

GameObject GetObjectFromPos(float x, float z)
{
    Vector3 pos = new Vector3(x, 0, z);

    rootGameObjects.Clear();
    childObjs.Clear();

    GetAllRootObject();
    GetAllChildObjs();

    //Loop through all Objects
    for (int i = 0; i < childObjs.Count; i++)
        //check  if x and z matches then return the Object
        if (xzEquals(childObjs[i].position, pos))
            return childObjs[i].gameObject;

    return null;
}

用法

//Get tag from x, z pos
Debug.Log(GetTagFromPos(1, 2));
//Get object from x, z pos
Debug.Log(GetObjectFromPos(1, 2));

如果您想在循环中节省一些时间,您也可以手动将要搜索的对象放入列表中。

【讨论】:

  • 我认为,在特定位置进行光线投射可能会更好。我想这将相当频繁地运行。或者可能减少只有在发生更改时才执行的获取所有对象调用的数量(否则每个级别一次可能就足够了)。在这种情况下,您可以构建一个查找表。
  • 我不知道 raycast 是否会这样做,因为 OP 没有解释它的用途,为什么他/她想要这个或多久调用一次,但只是询问如何将位置转换为一个对象标签。所以,我试图回答标题中的内容,假设它可能是场景中的任何对象
猜你喜欢
  • 2021-08-15
  • 2011-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多