修复了选曲的问题 优化了ui

This commit is contained in:
FloatGaming
2026-01-08 21:04:36 +08:00
parent e7f4ac72d5
commit 2738089af1
414 changed files with 60357 additions and 5279 deletions
@@ -21,6 +21,7 @@ public class loadDetailsPrefab : MonoBehaviour
private GameObject currentDetailsInstance;
private detailsPrefabController currentController;
private Coroutine showCoroutine;
private bool isAbove; // 是否在上方显示
void Awake()
{
@@ -36,6 +37,8 @@ public class loadDetailsPrefab : MonoBehaviour
if (detailsPrefab == null) return;
isAbove = (type == "技能"); // 技能在上方,英雄在下方
showCoroutine = StartCoroutine(ShowDetailsDelayed(type, name, status, description, position));
}
@@ -93,11 +96,53 @@ public class loadDetailsPrefab : MonoBehaviour
RectTransform canvasRect = canvas.GetComponent<RectTransform>();
// 计算动态偏移量
// 计算动态偏移量(垂直方向保持一致大小)
Vector2 dynamicOffset = CalculateDynamicOffset();
Vector2 baseScreenPos = new Vector2(position.x, position.y) + dynamicOffset;
Vector2 screenPos = new Vector2(position.x, position.y) + dynamicOffset;
// 计算 prefab 宽度(屏幕像素)并设置最大水平位移为 prefab 宽度(之前为一半)
float prefWidthPixels = rt.rect.width * (canvas != null ? canvas.scaleFactor : 1f);
float maxNudge = prefWidthPixels*4; // now allow up to full prefab width
// 以屏幕中心为基准计算鼠标水平偏离因子 (-1..1)
float screenCenterX = Screen.width * 0.5f;
float normalized = 0f;
if (screenCenterX > 0f)
normalized = (position.x - screenCenterX) / screenCenterX; // -1(left) .. 0(center) .. +1(right)
normalized = Mathf.Clamp(normalized, -1f, 1f);
// nudge 方向为向屏幕中心移动:鼠标在左侧(normalized<0)时,向右移动 (+),右侧相反
float nudge = -normalized * maxNudge;
Vector2 screenPos = baseScreenPos + new Vector2(nudge, 0f);
Vector3 initialPos = CalculateWorldPos(screenPos, canvas, canvasRect, rt);
// 如果初始位置超出画布,尝试翻转上下方并重新计算(保持相同垂直间距)
if (IsOutOfCanvas(initialPos, rt, canvas))
{
isAbove = !isAbove;
dynamicOffset = CalculateDynamicOffset();
baseScreenPos = new Vector2(position.x, position.y) + dynamicOffset;
// 重新计算 nudge(基于原始鼠标位置仍然有效)
normalized = 0f;
if (screenCenterX > 0f)
normalized = (position.x - screenCenterX) / screenCenterX;
normalized = Mathf.Clamp(normalized, -1f, 1f);
nudge = -normalized * maxNudge;
screenPos = baseScreenPos + new Vector2(nudge, 0f);
initialPos = CalculateWorldPos(screenPos, canvas, canvasRect, rt);
}
rt.position = initialPos;
// 最终调整以确保不超出(会修正剩余的左右/上下边界)
AdjustPositionWithinCanvas(rt, canvas);
}
private Vector3 CalculateWorldPos(Vector2 screenPos, Canvas canvas, RectTransform canvasRect, RectTransform rt)
{
if (canvas.renderMode == RenderMode.ScreenSpaceCamera && canvas.worldCamera != null)
{
Vector2 localPoint;
@@ -107,25 +152,45 @@ public class loadDetailsPrefab : MonoBehaviour
canvas.worldCamera,
out localPoint))
{
rt.anchoredPosition = localPoint;
return canvasRect.TransformPoint(localPoint);
}
else
{
rt.position = screenPos;
return screenPos;
}
}
else
{
float scaleFactor = canvas.scaleFactor;
Vector3 worldPos = new Vector3(
return new Vector3(
screenPos.x / scaleFactor,
screenPos.y / scaleFactor,
0
);
rt.position = worldPos;
}
}
AdjustPositionWithinCanvas(rt, canvas);
private bool IsOutOfCanvas(Vector3 pos, RectTransform rt, Canvas canvas)
{
RectTransform canvasRect = canvas.GetComponent<RectTransform>();
Vector3[] canvasCorners = new Vector3[4];
canvasRect.GetWorldCorners(canvasCorners);
float canvasLeft = canvasCorners[0].x;
float canvasRight = canvasCorners[2].x;
float canvasBottom = canvasCorners[0].y;
float canvasTop = canvasCorners[2].y;
// 临时设置位置以获取角落
Vector3 originalPos = rt.position;
rt.position = pos;
Vector3[] rtCorners = new Vector3[4];
rt.GetWorldCorners(rtCorners);
rt.position = originalPos;
// 检查是否完全在 Canvas 内
return rtCorners[0].x < canvasLeft || rtCorners[2].x > canvasRight ||
rtCorners[0].y < canvasBottom || rtCorners[2].y > canvasTop;
}
private Vector2 CalculateDynamicOffset()
@@ -140,12 +205,28 @@ public class loadDetailsPrefab : MonoBehaviour
screenHeight * offsetPercent.y
);
// 如果在上方,翻转Y偏移
if (isAbove)
{
percentOffset.y = -percentOffset.y;
}
// 应用最小像素偏移限制
Vector2 finalOffset = new Vector2(
Mathf.Abs(percentOffset.x) > Mathf.Abs(minOffsetPixels.x) ? percentOffset.x : minOffsetPixels.x,
Mathf.Abs(percentOffset.y) > Mathf.Abs(minOffsetPixels.y) ? percentOffset.y : minOffsetPixels.y
);
// 如果在上方,确保Y偏移为正
if (isAbove)
{
finalOffset.y = Mathf.Abs(finalOffset.y);
}
else
{
finalOffset.y = -Mathf.Abs(finalOffset.y);
}
return finalOffset;
}