技能主要更新,修复卡顿并加入动画,以及各种其他更新。
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
using System.Collections.Generic;
|
||||
using DG.Tweening;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class TeamSelectorMiniCardHover : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerMoveHandler
|
||||
{
|
||||
[SerializeField] float hoverScale = 1.05f;
|
||||
[SerializeField] float hoverTweenTime = 0.12f;
|
||||
[SerializeField] float hoverExpand = 0.18f;
|
||||
[SerializeField] float hoverCompress = 0.08f;
|
||||
[SerializeField] float gyroMaxAngle = 6f;
|
||||
[SerializeField] float gyroFollow = 8f;
|
||||
|
||||
bool isHovering;
|
||||
Camera lastEventCamera;
|
||||
LayoutElement layoutElement;
|
||||
|
||||
class LayoutInfo
|
||||
{
|
||||
public TeamSelectorMiniCardHover card;
|
||||
public LayoutElement layout;
|
||||
public float baseSize;
|
||||
}
|
||||
|
||||
static readonly Dictionary<Transform, List<LayoutInfo>> layoutCache = new();
|
||||
static readonly Dictionary<Transform, bool> layoutAxisIsHorizontal = new();
|
||||
|
||||
void Awake()
|
||||
{
|
||||
layoutElement = GetComponent<LayoutElement>() ?? gameObject.AddComponent<LayoutElement>();
|
||||
var g = GetComponent<Graphic>();
|
||||
if (g != null) g.raycastTarget = true;
|
||||
}
|
||||
|
||||
public void OnPointerEnter(PointerEventData eventData)
|
||||
{
|
||||
isHovering = true;
|
||||
lastEventCamera = eventData.enterEventCamera;
|
||||
ApplyHoverLayout(true);
|
||||
transform.DOKill();
|
||||
transform.DOScale(hoverScale, hoverTweenTime).SetEase(Ease.OutCubic);
|
||||
}
|
||||
|
||||
public void OnPointerExit(PointerEventData eventData)
|
||||
{
|
||||
isHovering = false;
|
||||
ApplyHoverLayout(false);
|
||||
transform.DOKill();
|
||||
transform.DOScale(1f, hoverTweenTime).SetEase(Ease.OutCubic);
|
||||
transform.localRotation = Quaternion.identity;
|
||||
}
|
||||
|
||||
public void OnPointerMove(PointerEventData eventData)
|
||||
{
|
||||
lastEventCamera = eventData.enterEventCamera;
|
||||
}
|
||||
|
||||
void LateUpdate()
|
||||
{
|
||||
if (!isHovering) return;
|
||||
RectTransform rt = transform as RectTransform;
|
||||
if (rt == null) return;
|
||||
if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(rt, Input.mousePosition, lastEventCamera, out Vector2 localPoint))
|
||||
return;
|
||||
Vector2 size = rt.rect.size;
|
||||
if (size.x <= 0f || size.y <= 0f) return;
|
||||
Vector2 norm = new Vector2(localPoint.x / size.x, localPoint.y / size.y);
|
||||
norm = Vector2.ClampMagnitude(norm * 2f, 1f);
|
||||
float xRot = -norm.y * gyroMaxAngle;
|
||||
float yRot = norm.x * gyroMaxAngle;
|
||||
Quaternion target = Quaternion.Euler(xRot, yRot, 0f);
|
||||
transform.localRotation = Quaternion.Slerp(transform.localRotation, target, Time.unscaledDeltaTime * gyroFollow);
|
||||
}
|
||||
|
||||
void ApplyHoverLayout(bool active)
|
||||
{
|
||||
Transform parent = transform.parent;
|
||||
if (parent == null) return;
|
||||
List<LayoutInfo> group = GetOrCacheGroup(parent);
|
||||
if (group == null || group.Count == 0) return;
|
||||
|
||||
bool horizontal = layoutAxisIsHorizontal.TryGetValue(parent, out bool h) ? h : true;
|
||||
for (int i = 0; i < group.Count; i++)
|
||||
{
|
||||
LayoutInfo info = group[i];
|
||||
if (info == null || info.layout == null) continue;
|
||||
float baseSize = info.baseSize;
|
||||
float target = baseSize;
|
||||
if (active)
|
||||
{
|
||||
target = info.card == this
|
||||
? baseSize * (1f + hoverExpand)
|
||||
: baseSize * Mathf.Max(0.1f, 1f - hoverCompress);
|
||||
}
|
||||
if (horizontal)
|
||||
info.layout.preferredWidth = target;
|
||||
else
|
||||
info.layout.preferredHeight = target;
|
||||
}
|
||||
ForceRebuildParentLayout();
|
||||
}
|
||||
|
||||
List<LayoutInfo> GetOrCacheGroup(Transform parent)
|
||||
{
|
||||
if (layoutCache.TryGetValue(parent, out var cached) && cached != null && cached.Count > 0)
|
||||
{
|
||||
return cached;
|
||||
}
|
||||
|
||||
bool horizontal = parent.GetComponent<HorizontalLayoutGroup>() != null;
|
||||
bool vertical = parent.GetComponent<VerticalLayoutGroup>() != null;
|
||||
layoutAxisIsHorizontal[parent] = !vertical || horizontal;
|
||||
|
||||
var list = new List<LayoutInfo>();
|
||||
TeamSelectorMiniCardHover[] cards = parent.GetComponentsInChildren<TeamSelectorMiniCardHover>(true);
|
||||
for (int i = 0; i < cards.Length; i++)
|
||||
{
|
||||
var card = cards[i];
|
||||
if (card == null) continue;
|
||||
var le = card.layoutElement ?? card.GetComponent<LayoutElement>() ?? card.gameObject.AddComponent<LayoutElement>();
|
||||
RectTransform rt = card.transform as RectTransform;
|
||||
float baseSize = 100f;
|
||||
if (rt != null)
|
||||
{
|
||||
baseSize = horizontal ? rt.rect.width : rt.rect.height;
|
||||
}
|
||||
if (horizontal)
|
||||
le.preferredWidth = baseSize;
|
||||
else
|
||||
le.preferredHeight = baseSize;
|
||||
list.Add(new LayoutInfo { card = card, layout = le, baseSize = baseSize });
|
||||
}
|
||||
layoutCache[parent] = list;
|
||||
return list;
|
||||
}
|
||||
|
||||
void ForceRebuildParentLayout()
|
||||
{
|
||||
if (transform.parent == null) return;
|
||||
RectTransform prt = transform.parent as RectTransform;
|
||||
if (prt != null)
|
||||
LayoutRebuilder.ForceRebuildLayoutImmediate(prt);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user