TheInitialProject/Assets/Scripts/UI/UIControl/ScreenAutoAdjust.cs
2024-10-23 16:59:02 +08:00

358 lines
13 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using CaoCao;
using Game.HotFix;
using UnityEngine;
using UnityEngine.UI;
public class ScreenAdjustMode
{
public static int M_16_9 = 0;
public static int M_18_9 = 1;
public static int M_16_12 = 2;
}
/// <summary>
/// 屏幕自适应 解决方案
/// </summary>
public class ScreenAutoAdjust : MonoBehaviour
{
public static ScreenAutoAdjust Instance;
public int mode;
public Vector2 screenPointMax;
//public Camera m_uiCamera;
//public Canvas m_Canvas; // 定死 固定用camera模式, 为了兼任UI粒子特效, 所以Canvas.RenderMode放弃了Overlay模式
public CanvasScaler m_CanvasScaler;
public UIMgr m_uiMgr;
public static readonly int DevWidth = 2568; // max 2972
public static readonly int DevHeight = 1284; // max 1712
private int mUseWidth = 0; // 自适应后使用的屏幕宽度
public int UseWidth { get { return mUseWidth; } }
private int mUseHeight = 0; // 自适应后使用的屏幕高度
public int UseHeight { get { return mUseHeight; } }
public int UseWay = 0;
public float mCameraRectWidthRate = 1f;
public float mCameraRectHeightRate = 1f;
private void Awake()
{
Instance = this;
//m_Canvas = transform.GetComponent<Canvas>();
m_CanvasScaler = transform.GetComponent<CanvasScaler>();
if (transform.parent)
{
m_uiMgr = transform.parent.GetComponent<UIMgr>();
}
m_CanvasScaler.referenceResolution = new Vector2(DevWidth, DevHeight);
}
private void Start()
{
//分辨率设置一定放到HotfixEntry.Init()之后,保证设置已读取)
//if (HotfixEntry.IsPC)
//{
// if (UICrossPlatform.IsNewPlan)
// HotfixEntry.SetGameScreen();
// else
// {
Vector2 targetXY = VivewResolution();
Screen.SetResolution((int)targetXY.x - 2, (int)targetXY.y, false);
CaoCaoLog.Debug($"目标宽高(热更)>>{targetXY.x}, {targetXY.y})");
// }
//}
//if (HotfixEntry.IsPC && UICrossPlatform.IsNewPlan)
//{
//}
//else
//{
// ScreenAutoAdapt();
//}
ScreenAutoAdapt();
}
#region
static float screenWidth = 2778;
static float screenHeight = 1284;
static Vector2 VivewResolution()
{
int currentheight = Screen.height;
//if (Display.displays.Length > 1)
// currentheight = Display.displays[0].renderingWidth;
int height = currentheight;
int width = (int)(height * screenWidth / screenHeight);
CaoCaoLog.Debug($"计算:{width}, {height})");
return new Vector2(width, height);
}
#endregion
// 屏幕自适应
public void ScreenAutoAdapt()
{
CaoCaoLog.Debug($"SCREEN:ScreenAutoAdapt {Screen.width} {(float)Screen.height} Screen.width / (float)Screen.height {Screen.width / (float)Screen.height}");
//float screenRate = Screen.width / (float)Screen.height;
float screenRate = (float)Common.GetCurrScreenSize().x / (float)Common.GetCurrScreenSize().y;
if (screenRate < 1.77f)
{
CaoCaoLog.Debug($"SCREEN:ScreenAutoAdapt1");
ScreenAutoAdapt1();
}
else
{
CaoCaoLog.Debug($"SCREEN:ScreenAutoAdapt2");
ScreenAutoAdapt2();
}
}
// 多出来的填充黑边的适应方式 4:3屏幕使用, 只要小于16:9 基本都是用这个 *:填充黑边的方式需要有摄像机
public void ScreenAutoAdapt1()
{
UseWay = 1;
int devWidth = DevWidth;
int devHeight = DevHeight;
mode = ScreenAdjustMode.M_16_12;
//屏幕比 > 2:1的用 2:1, 小于2:1的用16: 9
float screenRate = (float)Screen.width / (float)Screen.height;
devWidth = Mathf.FloorToInt(DevHeight * 16 / 9f);
if (m_uiMgr)
{
RectTransform rect = m_uiMgr.m_NodeUI.GetComponent<RectTransform>();
rect.sizeDelta = new Vector2(devWidth, devHeight);
RectTransform rect2 = m_uiMgr.m_NodeScreen.GetComponent<RectTransform>();
rect2.sizeDelta = new Vector2(devWidth, devHeight);
RectTransform rect3 = m_uiMgr.m_NodeLoading.GetComponent<RectTransform>();
rect3.sizeDelta = new Vector2(devWidth, devHeight);
m_uiMgr.m_RtfShelter.gameObject.SetActive(true);
m_uiMgr.m_RtfShelter.sizeDelta = new Vector2(0, devHeight);
}
//项目要使用的屏幕比
float devRate = (float)devWidth / (float)devHeight;
int useHeight = Screen.height;
int useWidth = Mathf.FloorToInt(devRate * useHeight);
if (screenRate < devRate)
{
useWidth = Screen.width;
useHeight = Mathf.FloorToInt((float)useWidth / devRate);
}
CaoCaoLog.Debug("Screen.width:" + Screen.width.ToString() + ", Screen.height:" + Screen.height.ToString());
//m_Canvas.renderMode = RenderMode.ScreenSpaceCamera;
UIMgr.Instance.IsScreenClip = true;
m_CanvasScaler.referenceResolution = new Vector2Int(devWidth, devHeight);
if (screenRate >= devRate)
m_CanvasScaler.matchWidthOrHeight = 1;
else
m_CanvasScaler.matchWidthOrHeight = 0;
float cameraRectWidthRate = 0f;
float cameraRectHeightRate = 0f;
CaoCaoLog.Debug("screenRate:" + screenRate.ToString() + ", devRate:" + devRate.ToString());
if (useWidth < devWidth)
{// 缩小
if (screenRate >= devRate)
{// 宽度缩小 高度不变
m_CanvasScaler.matchWidthOrHeight = 1;
cameraRectWidthRate = (float)devWidth / (float)Screen.width;
CaoCaoLog.Debug("cameraRectHeightRate1 cameraRectWidthRate:" + cameraRectWidthRate.ToString());
}
else
{// 高度缩小 宽不变
m_CanvasScaler.matchWidthOrHeight = 0;
cameraRectHeightRate = (float)useHeight / (float)Screen.height;
CaoCaoLog.Debug("cameraRectHeightRate2 cameraRectHeightRate:" + cameraRectHeightRate.ToString());
}
}
else
{// 放大
if (screenRate >= devRate)
{// 宽度缩小 高度不变
m_CanvasScaler.matchWidthOrHeight = 1;
cameraRectWidthRate = (float)useWidth / (float)Screen.width;
CaoCaoLog.Debug("cameraRectHeightRate3 cameraRectWidthRate:" + cameraRectWidthRate.ToString());
}
else
{// 高度缩小 宽不变
m_CanvasScaler.matchWidthOrHeight = 0;
cameraRectHeightRate = (float)useHeight / (float)Screen.height;
CaoCaoLog.Debug("cameraRectHeightRate4 cameraRectHeightRate:" + cameraRectHeightRate.ToString());
}
}
CaoCaoLog.Debug("Screen.width:" + Screen.width + ", Screen.height:" + Screen.height);
CaoCaoLog.Debug("useWidth:" + useWidth.ToString() + ", useHeight:" + useHeight.ToString());
mUseWidth = useWidth;
mUseHeight = useHeight;
mCameraRectWidthRate = cameraRectWidthRate;
mCameraRectHeightRate = cameraRectHeightRate;
}
// 改变NodeUI的大小适应方式 16:9 2:1的都用这个
public void ScreenAutoAdapt2()
{
UseWay = 2;
if(m_uiMgr)
m_uiMgr.m_RtfShelter.gameObject.SetActive(false);
int devWidth = DevWidth;
int devHeight = DevHeight;
mode = ScreenAdjustMode.M_18_9;
// 屏幕比 > 2:1的用 2:1, 小于2:1的用16:9
//float screenRate = Screen.width / (float)Screen.height;
float screenRate = Common.GetCurrScreenSize().x / (float)Common.GetCurrScreenSize().y;
CaoCaoLog.Debug($"SCREEN:ScreenAutoAdapt2:1 screenRate>{screenRate}");
if (screenRate < 1.98f)
{
CaoCaoLog.Debug($"SCREEN:ScreenAutoAdapt2:3 < 1.98f");
devWidth = DevHeight * 16 / 9;// 2283;//1920
mode = ScreenAdjustMode.M_16_9;
}
float devRate = devWidth / (float)devHeight;
//// 项目要使用的屏幕比
//int useHeight = Screen.height;
int useHeight = Common.GetCurrScreenSize().y;
int useWidth = Mathf.FloorToInt(devRate * useHeight);
if (screenRate < devRate)
{
CaoCaoLog.Debug($"SCREEN:ScreenAutoAdapt2:4 screenRate < devRate");
//useWidth = Screen.width;
useWidth = Common.GetCurrScreenSize().x;
useHeight = Mathf.FloorToInt(useWidth / devRate);
}
//screenPointMax.x = Screen.width;
//screenPointMax.y = Screen.height;
screenPointMax.x = Common.GetCurrScreenSize().x;
screenPointMax.y = Common.GetCurrScreenSize().y;
m_CanvasScaler.referenceResolution = new Vector2Int(devWidth, devHeight); // Vector2
CaoCaoLog.Debug($"SCREEN:ScreenAutoAdapt2:5 {devWidth},{devHeight}");
if (screenRate >= devRate)
{
CaoCaoLog.Debug($"SCREEN:ScreenAutoAdapt2:6 screenRate >= devRate");
m_CanvasScaler.matchWidthOrHeight = 1;
}
else
{
CaoCaoLog.Debug($"SCREEN:ScreenAutoAdapt2:6 else");
m_CanvasScaler.matchWidthOrHeight = 0;
}
if (m_uiMgr)
{
RectTransform rect = m_uiMgr.m_NodeUI.GetComponent<RectTransform>();
rect.sizeDelta = new Vector2(devWidth, devHeight);
RectTransform rect2 = m_uiMgr.m_NodeScreen.GetComponent<RectTransform>();
rect2.sizeDelta = new Vector2(devWidth, devHeight);
RectTransform rect3 = m_uiMgr.m_NodeLoading.GetComponent<RectTransform>();
rect3.sizeDelta = new Vector2(devWidth, devHeight);
}
CaoCaoLog.Debug("分辨率:Screen.width:" + Screen.width + ", Screen.height:" + Screen.height+ ", 安全区useWidth:" + useWidth.ToString() + ", useHeight:" + useHeight.ToString());
mUseWidth = useWidth;
mUseHeight = useHeight;
}
public float GetFullUIWidth()
{
int devWidth = DevWidth;
// 屏幕比 > 2:1的用 2:1, 小于2:1的用16:9
//float screenRate = (float)Screen.width / (float)Screen.height;
float screenRate = (float)Common.GetCurrScreenSize().x / (float)Common.GetCurrScreenSize().y;
if (screenRate < 1.98f)
devWidth = DevHeight * 16 / 9;
return Mathf.Max(screenRate * DevHeight, devWidth);
}
// 设置组件到鼠标点击屏幕位置
public void AutoSetToMousePos(RectTransform _rtf,Vector3 mousePos)
{
// 鼠标点击后的屏幕坐标
//var pos = Input.mousePosition;
var pos = mousePos;
//float showPosX = pos.x - Screen.width / 2;
//float showPosY = pos.y - Screen.height / 2;
float showPosX = pos.x - Common.GetCurrScreenSize().x / 2;
float showPosY = pos.y - Common.GetCurrScreenSize().y / 2;
if(UseWay == 1)
{
//showPosX = showPosX * (m_CanvasScaler.referenceResolution.x / Screen.width);
//showPosY = showPosY * (m_CanvasScaler.referenceResolution.y / UseHeight);
showPosX = showPosX * (m_CanvasScaler.referenceResolution.x / Common.GetCurrScreenSize().x);
showPosY = showPosY * (m_CanvasScaler.referenceResolution.y / UseHeight);
}
else
{
//showPosX = showPosX * (GetFullUIWidth() / Screen.width); // m_CanvasScaler.referenceResolution.x
//showPosY = showPosY * (m_CanvasScaler.referenceResolution.y / Screen.height);
showPosX = showPosX * (GetFullUIWidth() / Common.GetCurrScreenSize().x); // m_CanvasScaler.referenceResolution.x
showPosY = showPosY * (m_CanvasScaler.referenceResolution.y / Common.GetCurrScreenSize().y);
}
// 坐标限制在屏幕内
float rtfWidth = _rtf.rect.width;
float rtfHeight = _rtf.rect.height;
// CaoCaoLog.Debug("pos:" + pos.ToString() + ", rtfWidth:" + rtfWidth.ToString() + ", rtfHeight:" + rtfHeight.ToString() + ", UseWay:" + UseWay
//+ ", useScreen:[" + UseWidth + "," + UseHeight + "]" + ", Screen:[" + Screen.width + "," + Screen.height
//+ "], referenceResolution:" + m_CanvasScaler.referenceResolution.ToString());
float halfRtfWidth = rtfWidth / 2;
float halfRtfHeight = rtfHeight / 2;
int realyWidth = 0;
//if(Screen.width < Mathf.FloorToInt( m_CanvasScaler.referenceResolution.x))
// realyWidth = Mathf.Max(Screen.width, Mathf.FloorToInt( m_CanvasScaler.referenceResolution.x));
//else
// realyWidth = Mathf.Min(Screen.width, Mathf.FloorToInt(m_CanvasScaler.referenceResolution.x));
if (Common.GetCurrScreenSize().x < Mathf.FloorToInt(m_CanvasScaler.referenceResolution.x))
realyWidth = Mathf.Max(Common.GetCurrScreenSize().x, Mathf.FloorToInt(m_CanvasScaler.referenceResolution.x));
else
realyWidth = Mathf.Min(Common.GetCurrScreenSize().x, Mathf.FloorToInt(m_CanvasScaler.referenceResolution.x));
if (showPosX + rtfWidth > realyWidth/2)
showPosX -= halfRtfWidth;
else
showPosX += halfRtfWidth;
if(showPosY - rtfHeight < -m_CanvasScaler.referenceResolution.y/2)
showPosY += halfRtfHeight;
else
showPosY -= halfRtfHeight;
var screenPos = new Vector3(showPosX, showPosY, 0);
_rtf.transform.localPosition = screenPos;
}
}