在上篇文章(链接: link)中介绍的时适配CanvasScaler的部分模式,本篇将作为补充,也是最终版,适配Canvas Scaler的所有模式。
内容包含
- 核心代码:UIUtility.cs
- 测试代码:TestDrag.cs
代码:UIUtility
using UnityEngine;
using UnityEngine.UI;
public static class UIUtility
{
private static RectTransform canvasRect;
private static Canvas canvas;
private static CanvasScaler canvasScaler;
private static void Find()
{
var canvasObj = GameObject.Find("Canvas");
canvas = canvasObj.GetComponent<Canvas>();
canvasRect = canvasObj.transform as RectTransform;
canvasScaler = canvasObj.GetComponent<CanvasScaler>();
}
public static RectTransform CanvasRect
{
get
{
if (canvasRect == null) Find();
return canvasRect;
}
}
public static Canvas Canvas
{
get
{
if (canvas == null) Find();
return canvas;
}
}
public static CanvasScaler CanvasScaler
{
get
{
if (canvasScaler == null) Find();
return canvasScaler;
}
}
/// <summary>UI比率,主要用于拖拽UI时适配各分辨率</summary>
public static float UIRate
{
get
{
float finalRate = -1;
switch (CanvasScaler.uiScaleMode)
{
case CanvasScaler.ScaleMode.ConstantPixelSize:
finalRate = 1 / CanvasScaler.scaleFactor;
break;
case CanvasScaler.ScaleMode.ScaleWithScreenSize:
switch (CanvasScaler.screenMatchMode)
{
case CanvasScaler.ScreenMatchMode.Expand:
// 哪个在变就计算哪个的比值
finalRate = CanvasWidth < CanvasScaler.referenceResolution.x ? CanvasHeight / Screen.height : CanvasWidth / Screen.width;
break;
case CanvasScaler.ScreenMatchMode.Shrink:
// 哪个在变就计算哪个的比值
finalRate = CanvasWidth > CanvasScaler.referenceResolution.x ? CanvasHeight / Screen.height : CanvasWidth / Screen.width;
break;
default:
Debug.LogError($"当前比值不支持该UI屏幕匹配模式:screenMatchMode:{CanvasScaler.screenMatchMode},请使用UIUtility.UIRate_Vector");
break;
}
break;
default:
Debug.LogError($"当前比值不支持该UI缩放模式:uiScaleMode:{CanvasScaler.uiScaleMode},请使用UIUtility.UIRate_Vector");
break;
}
return finalRate;
}
}
public static Vector2 UIRate_Vector
{
get
{
Vector2 result = new Vector2(-1, -1);
switch (CanvasScaler.uiScaleMode)
{
case CanvasScaler.ScaleMode.ScaleWithScreenSize:
switch (CanvasScaler.screenMatchMode)
{
case CanvasScaler.ScreenMatchMode.MatchWidthOrHeight:
result.x = CanvasWidth / Screen.width;
result.y = CanvasHeight / Screen.height;
break;
default:
Debug.LogError($"当前比值不支持该UI屏幕匹配模式:screenMatchMode:{CanvasScaler.screenMatchMode},请使用UIUtility.UIRate");
break;
}
break;
case CanvasScaler.ScaleMode.ConstantPhysicalSize:
result.x = CanvasWidth / Screen.width;
result.y = CanvasHeight / Screen.height;
break;
default:
Debug.LogError($"当前比值不支持该UI缩放模式:uiScaleMode:{CanvasScaler.uiScaleMode},请使用UIUtility.UIRate");
break;
}
return result;
}
}
/// <summary>获取画布的宽</summary>
public static float CanvasWidth => CanvasRect.rect.width;
/// <summary>获取画布的高</summary>
public static float CanvasHeight => CanvasRect.rect.height;
}
代码:TestDrag
using UnityEngine;
using UnityEngine.EventSystems;
public class TestDrag : MonoBehaviour, IDragHandler
{
private RectTransform m_Rect;
private void Awake()
{
m_Rect = transform as RectTransform;
}
public void OnDrag(PointerEventData eventData)
{
if (!eventData.dragging) return;
Vector2 delta = eventData.delta;
if (UIUtility.CanvasScaler.uiScaleMode == CanvasScaler.ScaleMode.ConstantPhysicalSize ||
(UIUtility.CanvasScaler.uiScaleMode == CanvasScaler.ScaleMode.ScaleWithScreenSize && UIUtility.CanvasScaler.screenMatchMode == CanvasScaler.ScreenMatchMode.MatchWidthOrHeight))
delta *= UIUtility.UIRate_Vector;
else
delta *= UIUtility.UIRate;
m_Rect.anchoredPosition += delta;
}
}
请自行根据项目修改,如有问题可私信