效果
效果一
|
![]() |
效果二
|
![]() |
核心代码
核心代码为:UpdatePivot(this RectTransform rectTransform, Vector2 pivot) 动态更改轴心点并保持位置不变。
其余两个函数为动画协程,没有DoTween插件时可以调用。
public static class UnityHelper
{
public static void UpdatePivot(this RectTransform rectTransform, Vector2 pivot)
{
if (rectTransform.pivot.Equals(pivot)) return;
var pos = rectTransform.anchoredPosition;
pos.x -= rectTransform.rect.width * (rectTransform.pivot.x - pivot.x);
pos.y -= rectTransform.rect.height * (rectTransform.pivot.y - pivot.y);
rectTransform.pivot = pivot;
rectTransform.anchoredPosition = pos;
}
public static IEnumerator TweenScale(this Transform transform, Vector3 scale, float duration)
{
var time = 0f;
var originalScale = transform.localScale;
while (time < duration)
{
time += Time.deltaTime;
transform.localScale = Vector3.Lerp(originalScale, scale, time / duration);
yield return new WaitForEndOfFrame();
}
transform.localScale = scale;
}
public static IEnumerator TweenAlpha(this CanvasGroup group, float alpha, float duration)
{
var time = 0f;
var originalAlpha = group.alpha;
while (time < duration)
{
group.alpha = Mathf.Lerp(originalAlpha, alpha, time / duration);
time += Time.deltaTime;
yield return new WaitForEndOfFrame();
}
group.alpha = alpha;
}
}
使用示例
效果一
using System.Collections;
using UnityEngine;
using DG.Tweening;
public class TestPivot : MonoBehaviour
{
private const float FadeDuration = 0.4f;
private RectTransform _rectTransform;
private void Start()
{
_rectTransform = GetComponent<RectTransform>();
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
if (_rectTransform.localScale.Equals(Vector3.zero))
{
Show();
}
else
{
Hide();
}
}
}
private void Show()
{
_rectTransform.UpdatePivot(Vector2.up);
// _rectTransform.DOScale(Vector3.one, 0.4f);
StartCoroutine(_rectTransform.TweenScale(Vector3.one, FadeDuration));
}
private void Hide()
{
_rectTransform.UpdatePivot(Vector2.right);
// _rectTransform.DOScale(Vector3.zero, 0.4f);
StartCoroutine(_rectTransform.TweenScale(Vector3.zero, FadeDuration));
}
}
效果二
using System.Collections;
using UnityEngine;
using DG.Tweening;
using UnityEngine.EventSystems;
public class TestPivot2 : MonoBehaviour, IPointerDownHandler
{
private const float FadeDuration = 0.4f;
private readonly Vector2 UIResolution = new Vector2(1920f, 1080f);
private CanvasGroup _group;
private RectTransform _rectTransform;
private void Start()
{
_group = GetComponent<CanvasGroup>();
_rectTransform = GetComponent<RectTransform>();
}
public void OnPointerDown(PointerEventData eventData)
{
_rectTransform.UpdatePivot(GetPivot(eventData.pressPosition));
//DoTween();
StartCoroutine(AnimTween());
}
private Vector2 GetPivot(Vector2 screenPosition)
{
var rectSize = new Vector2(_rectTransform.rect.width, _rectTransform.rect.height);
var offsetOfCenter = screenPosition - UIResolution / 2; // 距离中心点的偏移
var localPosition = offsetOfCenter + rectSize / 2; // 相对于自身的位置
return localPosition / rectSize;
}
private void DoTween()
{
_group.blocksRaycasts = false;
_rectTransform.localScale = Vector3.zero;
_rectTransform.DOScale(Vector3.one, FadeDuration);
var tweenSequence = DOTween.Sequence();
tweenSequence.Append(_group.DOFade(1, FadeDuration));
tweenSequence.Append(_group.DOFade(0, FadeDuration).SetDelay(FadeDuration).OnComplete(() => { _group.blocksRaycasts = true; }));
}
private IEnumerator AnimTween()
{
_group.blocksRaycasts = false;
_rectTransform.localScale = Vector3.zero;
StartCoroutine(_rectTransform.TweenScale(Vector3.one, FadeDuration));
yield return _group.TweenAlpha(1, FadeDuration);
yield return new WaitForSeconds(FadeDuration);
yield return _group.TweenAlpha(0, FadeDuration);
_group.blocksRaycasts = true;
}
}