Demo链接:
https://download.csdn.net/download/qq_41973169/89439428https://download.csdn.net/download/qq_41973169/89439428
一、前言
Unity版本:2020.1.x
如果需要资源请联系我我会分享给你 因为本人也要存储一下Demo所以上传到这里了但是又不能设置不需要积分
在Unity游戏开发中,滚动视图中元素的定位是一个常见需求。为了解决这个问题,我们可以编写一个名为 "ScrollLocate" 的脚本来实现这个功能。
二、效果
三、完整代码
代码都有注释逻辑也很简单故不再阐述
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ScrollLocate : MonoBehaviour
{
public RectTransform targetTransform;
private ScrollRect _scrollRect;
private RectTransform _scrollRectTransform;
private RectTransform _contentTransform;
private RectTransform _viewPortTransform;
// 测试代码
public int locateIndex = 1;
private List<RectTransform> _allTargetRects;
private void Start()
{
_scrollRect = GetComponent<ScrollRect>();
_contentTransform = _scrollRect.content;
_viewPortTransform = _scrollRect.viewport;
_scrollRectTransform = GetComponent<RectTransform>();
//测试代码
_allTargetRects = new List<RectTransform>();
for (int i = 0; i < 20; i++)
{
GameObject targetObj = Instantiate(targetTransform.gameObject, _contentTransform.transform);
Text text = targetObj.transform.GetChild(0).GetComponent<Text>();
text.text = (i + 2).ToString();
_allTargetRects.Add(targetObj.GetComponent<RectTransform>());
}
}
//测试代码
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
LocateTargetInViewportCenter(_allTargetRects[locateIndex - 1]);
}
}
// 将目标元素定位到视口中心
void LocateTargetInViewportCenter(RectTransform targetRect)
{
// 将目标元素的当前本地坐标转换为滚动视图的局部坐标系中的位置
Vector3 targetCurrentLocalPosition = _scrollRectTransform.InverseTransformVector(ConvertLocalPosToWorldPos(targetRect));
// 将视口的当前本地坐标转换为滚动视图的局部坐标系中的位置
Vector3 viewportCurrentLocalPosition = _scrollRectTransform.InverseTransformVector(ConvertLocalPosToWorldPos(_viewPortTransform));
// 计算目标元素在滚动视图中的偏移量
Vector3 offset = viewportCurrentLocalPosition - targetCurrentLocalPosition;
offset.z = 0.0f;
// 计算偏移量在滚动视图 normalizedPosition 中的比例
var normalizedOffset = new Vector2(
offset.x / (_contentTransform.rect.width - _viewPortTransform.rect.width),
offset.y / (_contentTransform.rect.height - _viewPortTransform.rect.height)
);
// 根据偏移量调整滚动视图的 normalizedPosition
var newNormalizedPosition = _scrollRect.normalizedPosition - normalizedOffset;
// 对新的 normalizedPosition 进行边界限制,确保其在合理范围内
newNormalizedPosition.x = Mathf.Clamp01(newNormalizedPosition.x);
newNormalizedPosition.y = Mathf.Clamp01(newNormalizedPosition.y);
_scrollRect.normalizedPosition = newNormalizedPosition;
}
// 将目标元素本地坐标转换为世界坐标
private Vector3 ConvertLocalPosToWorldPos(RectTransform targetRect)
{
// 计算目标 RectTransform 中心点在父对象空间中的位置偏移量
var centerOffset = new Vector3(
(0.5f - targetRect.pivot.x) * targetRect.rect.size.x,
(0.5f - targetRect.pivot.y) * targetRect.rect.size.y,
0f);
// 将目标元素的本地坐标与偏移量相加,得到世界坐标
var localPosition = targetRect.localPosition + centerOffset;
return targetRect.parent.TransformPoint(localPosition);
}
}