修复了选曲的问题 优化了ui
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user