Unity获取物体位置

img


我使用了Scroll View一个组件,然后动态生成列表,在组件中挂载了content size fitter和vertical layout group,生成的预制体也加载了这两个控件,我现在需要获取列表里面生成预制体的位置,但是我使用了normalizedPosition、localPosition、anchoredPosition和position但是获取的位置都与子物体的实际位置不同。

img

这是子物体的属性:

img

这是我使用position获取的位置:

img

同时生成的后面预制体获取的位置都是0

img

img

using UnityEngine;
using UnityEngine.UI;
public class NewBehaviourScript : MonoBehaviour
{
    public int index;
    public Transform itemPrefab;
    public RectTransform img;
    ScrollRect scrollRect;
    RectTransform content;
    VerticalLayoutGroup layoutGroup;
    Rect displayArea;
    void Start()
    {
        scrollRect = GetComponent<ScrollRect>();
        content = scrollRect.content;

        layoutGroup = content.GetComponent<VerticalLayoutGroup>();
        itemPrefab.gameObject.SetActive(false);
        for (var i = 0; i < 20; i++)
        {
            var go = GameObject.Instantiate(itemPrefab.gameObject);
            go.SetActive(true);
            go.gameObject.name = i.ToString();
            go.transform.SetParent(content);
            go.GetComponentInChildren<Text>().text = i.ToString();
        }
    }

    private void LateUpdate()
    {
        displayArea = new Rect(Vector2.zero, (scrollRect.transform as RectTransform).sizeDelta + scrollRect.viewport.sizeDelta);
        if (scrollRect.content.childCount < index)
            return;

        var contentPos = content.anchoredPosition + GetPivotOffset(content) + GetPaddingOffset();
        var itrmTr = (scrollRect.content.GetChild(index) as RectTransform);
        var pos = itrmTr.anchoredPosition + GetPivotOffset(itrmTr);

        img.anchoredPosition = pos + contentPos;
        img.sizeDelta = itrmTr.sizeDelta;

        //由于Y方向不同需要 乘以 -1
        Debug.Log($"{index}是否显示:{displayArea.Overlaps(new Rect(img.anchoredPosition * new Vector2(1, -1), img.sizeDelta))}");
    }
    //垂直布局偏移
    Vector2 GetPaddingOffset()
    {
        return new Vector2(layoutGroup.padding.left, -layoutGroup.padding.top);
    }
    //中心点偏移
    Vector2 GetPivotOffset(RectTransform tr)
    {
        return (new Vector2(0, 1) - tr.pivot) * tr.sizeDelta;
    }
}

https://www.shuzhiduo.com/topic/unity-%E8%8E%B7%E5%8F%96%E7%89%A9%E4%BD%93%E5%B1%8F%E5%B9%95%E5%9D%90%E6%A0%87/

用了contentsize组件就不能用position相关的api了。

img


你用rect,我这里举个例子,关于位置计算你可以根据你的计算方式来,我这里并不精确。

这是一篇实例中的思路【unity中生成一个预设体后怎样获取该预设体的子物体的坐标】

img

有几种方法可以获取物体在Unity中的位置:

使用transform.position属性。这是一个Vector3类型的变量,包含物体的x、y、z坐标。例如:
Vector3 position = transform.position;

使用transform.localPosition属性。这也是一个Vector3类型的变量,表示物体的位置相对于父物体的坐标。例如:
Vector3 localPosition = transform.localPosition;

使用GameObject.Find()函数。这是一种通过物体的名称来查找物体的方法,并返回该物体的Transform组件。然后可以使用Transform.position属性获取物体的位置。例如:
Transform objectTransform = GameObject.Find("ObjectName").transform;
Vector3 position = objectTransform.position;

使用Raycast函数。这是一种通过从摄像机或其他物体发射射线来检测到物体的方法。可以使用RaycastHit变量获取物体的位置。例如:
RaycastHit hit;
if (Physics.Raycast(transform.position, transform.forward, out hit))
{
Vector3 position = hit.transform.position;
}

注意:上述方法都需要先在Unity场景中添加物体,并为其添加Transform组件。