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