using DG.Tweening; using UnityEngine; using UnityEngine.UI; public class ScrollViewNevigation : MonoBehaviour { public ScrollRect scrollRect; public RectTransform viewport; public RectTransform content; void Start() { Init(); } private void Init() { if (scrollRect == null) { scrollRect = this.GetComponent(); } if (viewport == null) { viewport = this.transform.Find("Viewport").GetComponent(); } if (content == null) { content = this.transform.Find("Viewport/Content").GetComponent(); } } public void Nevigate(RectTransform item) { if (item == null) return; Vector3 itemCurrentLocalPostion = scrollRect.GetComponent().InverseTransformVector(ConvertLocalPosToWorldPos(item)); Vector3 itemTargetLocalPos = scrollRect.GetComponent().InverseTransformVector(ConvertLocalPosToWorldPos(viewport)); Vector3 diff = itemTargetLocalPos - itemCurrentLocalPostion; diff.z = 0.0f; var newNormalizedPosition = new Vector2( diff.x / (content.GetComponent().rect.width - viewport.rect.width), diff.y / (content.GetComponent().rect.height - viewport.rect.height) ); newNormalizedPosition = scrollRect.GetComponent().normalizedPosition - newNormalizedPosition; newNormalizedPosition.x = Mathf.Clamp01(newNormalizedPosition.x); newNormalizedPosition.y = Mathf.Clamp01(newNormalizedPosition.y); //有DOTween时使用 DOTween.To(() => scrollRect.GetComponent().normalizedPosition, x => scrollRect.GetComponent().normalizedPosition = x, newNormalizedPosition, 0.8f); //无DOTween时使用 //scrollRect.GetComponent().normalizedPosition = newNormalizedPosition; } private Vector3 ConvertLocalPosToWorldPos(RectTransform target) { var pivotOffset = new Vector3( (0.5f - target.pivot.x) * target.rect.size.x, (0.5f - target.pivot.y) * target.rect.size.y, 0f); var localPosition = target.localPosition + pivotOffset; return target.parent.TransformPoint(localPosition); } }