因为item的坐标已经被引擎计算过了
所以只需要处理LayoutGroup的Padding即可
实际的坐标只需要先计算content的坐标再计算子元素偏移
最后相加就是实际item当前位置
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;
}
}
跳转到子对象
var itrmTr = (scrollRect.content.GetChild(index) as RectTransform);
var pos = itrmTr.anchoredPosition + GetPivotOffset(itrmTr);
scrollRect.content.anchoredPosition = new Vector2(0,-pos.y);