using UnityEngine;
namespace FairyGUI
{
///
///
///
[ExecuteInEditMode]
[AddComponentMenu("FairyGUI/UI Content Scaler")]
public class UIContentScaler : MonoBehaviour
{
///
///
///
public enum ScaleMode
{
ConstantPixelSize,
ScaleWithScreenSize,
ConstantPhysicalSize
}
///
///
///
public enum ScreenMatchMode
{
MatchWidthOrHeight,
MatchWidth,
MatchHeight
}
///
///
///
public ScaleMode scaleMode;
///
///
///
public ScreenMatchMode screenMatchMode;
///
///
///
public int designResolutionX;
///
///
///
public int designResolutionY;
///
///
///
public int fallbackScreenDPI = 96;
///
///
///
public int defaultSpriteDPI = 96;
///
///
///
public float constantScaleFactor = 1;
///
/// 当false时,计算比例时会考虑designResolutionX/Y的设置是针对横屏还是竖屏。否则不考虑。
///
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();
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
///
///
///
public void ApplyModifiedProperties()
{
_changed = true;
}
///
///
///
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;
}
}
}