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; } } }