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