UIContentScaler.cs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. using UnityEngine;
  2. namespace FairyGUI
  3. {
  4. /// <summary>
  5. ///
  6. /// </summary>
  7. [ExecuteInEditMode]
  8. [AddComponentMenu("FairyGUI/UI Content Scaler")]
  9. public class UIContentScaler : MonoBehaviour
  10. {
  11. /// <summary>
  12. ///
  13. /// </summary>
  14. public enum ScaleMode
  15. {
  16. ConstantPixelSize,
  17. ScaleWithScreenSize,
  18. ConstantPhysicalSize
  19. }
  20. /// <summary>
  21. ///
  22. /// </summary>
  23. public enum ScreenMatchMode
  24. {
  25. MatchWidthOrHeight,
  26. MatchWidth,
  27. MatchHeight
  28. }
  29. /// <summary>
  30. ///
  31. /// </summary>
  32. public ScaleMode scaleMode;
  33. /// <summary>
  34. ///
  35. /// </summary>
  36. public ScreenMatchMode screenMatchMode;
  37. /// <summary>
  38. ///
  39. /// </summary>
  40. public int designResolutionX;
  41. /// <summary>
  42. ///
  43. /// </summary>
  44. public int designResolutionY;
  45. /// <summary>
  46. ///
  47. /// </summary>
  48. public int fallbackScreenDPI = 96;
  49. /// <summary>
  50. ///
  51. /// </summary>
  52. public int defaultSpriteDPI = 96;
  53. /// <summary>
  54. ///
  55. /// </summary>
  56. public float constantScaleFactor = 1;
  57. /// <summary>
  58. /// 当false时,计算比例时会考虑designResolutionX/Y的设置是针对横屏还是竖屏。否则不考虑。
  59. /// </summary>
  60. public bool ignoreOrientation = false;
  61. [System.NonSerialized]
  62. public static float scaleFactor = 1;
  63. [System.NonSerialized]
  64. public static int scaleLevel = 0;
  65. [System.NonSerialized]
  66. bool _changed;
  67. void OnEnable()
  68. {
  69. if (Application.isPlaying)
  70. {
  71. //播放模式下都是通过Stage自带的UIContentScaler实现调整的,所以这里只是把参数传过去
  72. UIContentScaler scaler = Stage.inst.gameObject.GetComponent<UIContentScaler>();
  73. if (scaler != this)
  74. {
  75. scaler.scaleMode = scaleMode;
  76. if (scaleMode == ScaleMode.ScaleWithScreenSize)
  77. {
  78. scaler.designResolutionX = designResolutionX;
  79. scaler.designResolutionY = designResolutionY;
  80. scaler.screenMatchMode = screenMatchMode;
  81. scaler.ignoreOrientation = ignoreOrientation;
  82. }
  83. else if (scaleMode == ScaleMode.ConstantPhysicalSize)
  84. {
  85. scaler.fallbackScreenDPI = fallbackScreenDPI;
  86. scaler.defaultSpriteDPI = defaultSpriteDPI;
  87. }
  88. else
  89. {
  90. scaler.constantScaleFactor = constantScaleFactor;
  91. }
  92. scaler.ApplyChange();
  93. GRoot.inst.ApplyContentScaleFactor();
  94. }
  95. }
  96. else //Screen width/height is not reliable in OnEnable in editmode
  97. _changed = true;
  98. }
  99. void Update()
  100. {
  101. if (_changed)
  102. {
  103. _changed = false;
  104. ApplyChange();
  105. }
  106. }
  107. void OnDestroy()
  108. {
  109. if (!Application.isPlaying)
  110. {
  111. scaleFactor = 1;
  112. scaleLevel = 0;
  113. }
  114. }
  115. //For UIContentScalerEditor Only, as the Screen.width/height is not correct in OnInspectorGUI
  116. /// <summary>
  117. ///
  118. /// </summary>
  119. public void ApplyModifiedProperties()
  120. {
  121. _changed = true;
  122. }
  123. /// <summary>
  124. ///
  125. /// </summary>
  126. public void ApplyChange()
  127. {
  128. float screenWidth;
  129. float screenHeight;
  130. if (Application.isPlaying) //In case of multi display, we keep using the display which Stage object resides.
  131. {
  132. screenWidth = Stage.inst.width;
  133. screenHeight = Stage.inst.height;
  134. }
  135. else
  136. {
  137. screenWidth = Screen.width;
  138. screenHeight = Screen.height;
  139. }
  140. if (scaleMode == ScaleMode.ScaleWithScreenSize)
  141. {
  142. if (designResolutionX == 0 || designResolutionY == 0)
  143. return;
  144. int dx = designResolutionX;
  145. int dy = designResolutionY;
  146. if (!ignoreOrientation && (screenWidth > screenHeight && dx < dy || screenWidth < screenHeight && dx > dy))
  147. {
  148. //scale should not change when orientation change
  149. int tmp = dx;
  150. dx = dy;
  151. dy = tmp;
  152. }
  153. if (screenMatchMode == ScreenMatchMode.MatchWidthOrHeight)
  154. {
  155. float s1 = (float)screenWidth / dx;
  156. float s2 = (float)screenHeight / dy;
  157. scaleFactor = Mathf.Min(s1, s2);
  158. }
  159. else if (screenMatchMode == ScreenMatchMode.MatchWidth)
  160. scaleFactor = (float)screenWidth / dx;
  161. else
  162. scaleFactor = (float)screenHeight / dy;
  163. }
  164. else if (scaleMode == ScaleMode.ConstantPhysicalSize)
  165. {
  166. float dpi = Screen.dpi;
  167. if (dpi == 0)
  168. dpi = fallbackScreenDPI;
  169. if (dpi == 0)
  170. dpi = 96;
  171. scaleFactor = dpi / (defaultSpriteDPI == 0 ? 96 : defaultSpriteDPI);
  172. }
  173. else
  174. scaleFactor = constantScaleFactor;
  175. if (scaleFactor > 10)
  176. scaleFactor = 10;
  177. UpdateScaleLevel();
  178. StageCamera.screenSizeVer++;
  179. }
  180. void UpdateScaleLevel()
  181. {
  182. if (scaleFactor > 3)
  183. scaleLevel = 3; //x4
  184. else if (scaleFactor > 2)
  185. scaleLevel = 2; //x3
  186. else if (scaleFactor > 1)
  187. scaleLevel = 1; //x2
  188. else
  189. scaleLevel = 0;
  190. }
  191. }
  192. }