2025-06-07 17:43:34 +08:00

218 lines
6.2 KiB
C#
Raw Permalink 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 UnityEngine;
namespace FairyGUI
{
/// <summary>
///
/// </summary>
[ExecuteInEditMode]
[AddComponentMenu("FairyGUI/UI Content Scaler")]
public class UIContentScaler : MonoBehaviour
{
/// <summary>
///
/// </summary>
public enum ScaleMode
{
ConstantPixelSize,
ScaleWithScreenSize,
ConstantPhysicalSize
}
/// <summary>
///
/// </summary>
public enum ScreenMatchMode
{
MatchWidthOrHeight,
MatchWidth,
MatchHeight
}
/// <summary>
///
/// </summary>
public ScaleMode scaleMode;
/// <summary>
///
/// </summary>
public ScreenMatchMode screenMatchMode;
/// <summary>
///
/// </summary>
public int designResolutionX;
/// <summary>
///
/// </summary>
public int designResolutionY;
/// <summary>
///
/// </summary>
public int fallbackScreenDPI = 96;
/// <summary>
///
/// </summary>
public int defaultSpriteDPI = 96;
/// <summary>
///
/// </summary>
public float constantScaleFactor = 1;
/// <summary>
/// 当false时计算比例时会考虑designResolutionX/Y的设置是针对横屏还是竖屏。否则不考虑。
/// </summary>
public bool ignoreOrientation = false;
[System.NonSerialized]
public static float scaleFactor = 1;
[System.NonSerialized]
public static int scaleLevel = 0;
[System.NonSerialized]
bool _changed;
void OnEnable()
{
if (Application.isPlaying)
{
//播放模式下都是通过Stage自带的UIContentScaler实现调整的所以这里只是把参数传过去
UIContentScaler scaler = Stage.inst.gameObject.GetComponent<UIContentScaler>();
if (scaler != this)
{
scaler.scaleMode = scaleMode;
if (scaleMode == ScaleMode.ScaleWithScreenSize)
{
scaler.designResolutionX = designResolutionX;
scaler.designResolutionY = designResolutionY;
scaler.screenMatchMode = screenMatchMode;
scaler.ignoreOrientation = ignoreOrientation;
}
else if (scaleMode == ScaleMode.ConstantPhysicalSize)
{
scaler.fallbackScreenDPI = fallbackScreenDPI;
scaler.defaultSpriteDPI = defaultSpriteDPI;
}
else
{
scaler.constantScaleFactor = constantScaleFactor;
}
scaler.ApplyChange();
GRoot.inst.ApplyContentScaleFactor();
}
}
else //Screen width/height is not reliable in OnEnable in editmode
_changed = true;
}
void Update()
{
if (_changed)
{
_changed = false;
ApplyChange();
}
}
void OnDestroy()
{
if (!Application.isPlaying)
{
scaleFactor = 1;
scaleLevel = 0;
}
}
//For UIContentScalerEditor Only, as the Screen.width/height is not correct in OnInspectorGUI
/// <summary>
///
/// </summary>
public void ApplyModifiedProperties()
{
_changed = true;
}
/// <summary>
///
/// </summary>
public void ApplyChange()
{
float screenWidth;
float screenHeight;
if (Application.isPlaying) //In case of multi display we keep using the display which Stage object resides.
{
screenWidth = Stage.inst.width;
screenHeight = Stage.inst.height;
}
else
{
screenWidth = Screen.width;
screenHeight = Screen.height;
}
if (scaleMode == ScaleMode.ScaleWithScreenSize)
{
if (designResolutionX == 0 || designResolutionY == 0)
return;
int dx = designResolutionX;
int dy = designResolutionY;
if (!ignoreOrientation && (screenWidth > screenHeight && dx < dy || screenWidth < screenHeight && dx > dy))
{
//scale should not change when orientation change
int tmp = dx;
dx = dy;
dy = tmp;
}
if (screenMatchMode == ScreenMatchMode.MatchWidthOrHeight)
{
float s1 = (float)screenWidth / dx;
float s2 = (float)screenHeight / dy;
scaleFactor = Mathf.Min(s1, s2);
}
else if (screenMatchMode == ScreenMatchMode.MatchWidth)
scaleFactor = (float)screenWidth / dx;
else
scaleFactor = (float)screenHeight / dy;
}
else if (scaleMode == ScaleMode.ConstantPhysicalSize)
{
float dpi = Screen.dpi;
if (dpi == 0)
dpi = fallbackScreenDPI;
if (dpi == 0)
dpi = 96;
scaleFactor = dpi / (defaultSpriteDPI == 0 ? 96 : defaultSpriteDPI);
}
else
scaleFactor = constantScaleFactor;
if (scaleFactor > 10)
scaleFactor = 10;
UpdateScaleLevel();
StageCamera.screenSizeVer++;
}
void UpdateScaleLevel()
{
if (scaleFactor > 3)
scaleLevel = 3; //x4
else if (scaleFactor > 2)
scaleLevel = 2; //x3
else if (scaleFactor > 1)
scaleLevel = 1; //x2
else
scaleLevel = 0;
}
}
}