TextQualityOptimizer.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. using UnityEngine;
  2. using UnityEngine.UI;
  3. using TMPro;
  4. public class TextQualityOptimizer : MonoBehaviour
  5. {
  6. [Header("文字质量优化设置")]
  7. [SerializeField] private bool enableHighDPI = true; // 启用高DPI支持
  8. [SerializeField] private float resolutionScale = 2.0f; // 分辨率缩放
  9. [SerializeField] private bool usePixelPerfect = true; // 像素完美模式
  10. [SerializeField] private FilterMode preferredFilterMode = FilterMode.Bilinear; // 首选过滤模式
  11. [SerializeField] private bool enableMSAA = true; // 启用多重采样抗锯齿
  12. [Header("字体优化")]
  13. [SerializeField] private bool useBitmapFont = false; // 使用位图字体
  14. [SerializeField] private int fontTextureSize = 1024; // 字体纹理大小
  15. [SerializeField] private bool enableFontSmoothing = true; // 启用字体平滑
  16. [Header("Canvas优化")]
  17. [SerializeField] private bool useRenderTexture = false; // 使用渲染纹理
  18. [SerializeField] private int renderTextureWidth = 2048; // 渲染纹理宽度
  19. [SerializeField] private int renderTextureHeight = 1024; // 渲染纹理高度
  20. [SerializeField] private bool enableCanvasOptimization = true; // 启用Canvas优化
  21. private Camera mainCamera;
  22. private Canvas[] sceneCanvases;
  23. void Start()
  24. {
  25. mainCamera = Camera.main;
  26. if (mainCamera == null)
  27. {
  28. mainCamera = FindObjectOfType<Camera>();
  29. }
  30. // 应用质量设置
  31. ApplyQualitySettings();
  32. // 优化场景中的Canvas
  33. OptimizeSceneCanvases();
  34. }
  35. [ContextMenu("应用质量优化")]
  36. public void ApplyQualitySettings()
  37. {
  38. // 设置高DPI支持
  39. if (enableHighDPI)
  40. {
  41. Screen.SetResolution(Screen.currentResolution.width, Screen.currentResolution.height, true);
  42. }
  43. // 设置抗锯齿
  44. if (enableMSAA)
  45. {
  46. QualitySettings.antiAliasing = 4; // 4x MSAA
  47. }
  48. // 设置纹理质量
  49. QualitySettings.masterTextureLimit = 0; // 最高质量
  50. QualitySettings.anisotropicFiltering = AnisotropicFiltering.ForceEnable;
  51. Debug.Log("已应用文字质量优化设置");
  52. }
  53. [ContextMenu("优化场景Canvas")]
  54. public void OptimizeSceneCanvases()
  55. {
  56. sceneCanvases = FindObjectsOfType<Canvas>();
  57. foreach (Canvas canvas in sceneCanvases)
  58. {
  59. OptimizeCanvas(canvas);
  60. }
  61. Debug.Log($"已优化 {sceneCanvases.Length} 个Canvas");
  62. }
  63. private void OptimizeCanvas(Canvas canvas)
  64. {
  65. if (!enableCanvasOptimization) return;
  66. // 优化CanvasScaler
  67. CanvasScaler scaler = canvas.GetComponent<CanvasScaler>();
  68. if (scaler != null)
  69. {
  70. scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
  71. scaler.referenceResolution = new Vector2(1920, 1080);
  72. scaler.screenMatchMode = CanvasScaler.ScreenMatchMode.MatchWidthOrHeight;
  73. scaler.matchWidthOrHeight = 0.5f;
  74. }
  75. // 优化Canvas设置
  76. canvas.additionalShaderChannels |= AdditionalCanvasShaderChannels.Normal;
  77. canvas.additionalShaderChannels |= AdditionalCanvasShaderChannels.Tangent;
  78. // 优化所有Text组件
  79. Text[] texts = canvas.GetComponentsInChildren<Text>();
  80. foreach (Text text in texts)
  81. {
  82. OptimizeText(text);
  83. }
  84. // 优化所有TextMeshPro组件
  85. TextMeshProUGUI[] tmpTexts = canvas.GetComponentsInChildren<TextMeshProUGUI>();
  86. foreach (TextMeshProUGUI tmp in tmpTexts)
  87. {
  88. OptimizeTextMeshPro(tmp);
  89. }
  90. }
  91. private void OptimizeText(Text text)
  92. {
  93. if (text == null) return;
  94. // 设置高质量文字属性
  95. text.horizontalOverflow = HorizontalWrapMode.Overflow;
  96. text.verticalOverflow = VerticalWrapMode.Overflow;
  97. text.resizeTextForBestFit = false;
  98. text.supportRichText = false;
  99. text.fontStyle = FontStyle.Normal;
  100. // 应用分辨率缩放
  101. if (resolutionScale > 1.0f)
  102. {
  103. text.fontSize = (int)(text.fontSize * resolutionScale);
  104. text.transform.localScale = Vector3.one / resolutionScale;
  105. }
  106. // 优化材质
  107. if (text.material != null)
  108. {
  109. text.material.SetFloat("_SrcBlend", (float)UnityEngine.Rendering.BlendMode.SrcAlpha);
  110. text.material.SetFloat("_DstBlend", (float)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
  111. text.material.SetFloat("_ZWrite", 0);
  112. text.material.DisableKeyword("_ALPHATEST_ON");
  113. text.material.EnableKeyword("_ALPHABLEND_ON");
  114. text.material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
  115. text.material.renderQueue = 3000;
  116. }
  117. }
  118. private void OptimizeTextMeshPro(TextMeshProUGUI tmp)
  119. {
  120. if (tmp == null) return;
  121. // 设置高质量TextMeshPro属性
  122. tmp.enableAutoSizing = false;
  123. tmp.fontStyle = FontStyles.Normal;
  124. tmp.enableWordWrapping = false;
  125. tmp.richText = false;
  126. tmp.raycastTarget = false; // 如果不需要交互
  127. // 应用分辨率缩放
  128. if (resolutionScale > 1.0f)
  129. {
  130. tmp.fontSize = tmp.fontSize * resolutionScale;
  131. tmp.transform.localScale = Vector3.one / resolutionScale;
  132. }
  133. // 优化材质
  134. if (tmp.material != null)
  135. {
  136. tmp.material.SetFloat("_UnderlayDilate", 0.0f);
  137. tmp.material.SetFloat("_UnderlaySoftness", 0.0f);
  138. tmp.material.SetFloat("_WeightNormal", 0.5f);
  139. tmp.material.SetFloat("_WeightBold", 0.75f);
  140. tmp.material.SetFloat("_OutlineWidth", 0.0f);
  141. tmp.material.SetFloat("_FaceDilate", 0.0f);
  142. tmp.material.SetFloat("_FaceSoftness", 0.0f);
  143. }
  144. }
  145. [ContextMenu("创建高质量字体材质")]
  146. public void CreateHighQualityFontMaterial()
  147. {
  148. // 创建高质量字体材质
  149. Material highQualityMaterial = new Material(Shader.Find("UI/Default"));
  150. // 设置高质量属性
  151. highQualityMaterial.SetFloat("_SrcBlend", (float)UnityEngine.Rendering.BlendMode.SrcAlpha);
  152. highQualityMaterial.SetFloat("_DstBlend", (float)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
  153. highQualityMaterial.SetFloat("_ZWrite", 0);
  154. highQualityMaterial.DisableKeyword("_ALPHATEST_ON");
  155. highQualityMaterial.EnableKeyword("_ALPHABLEND_ON");
  156. highQualityMaterial.DisableKeyword("_ALPHAPREMULTIPLY_ON");
  157. highQualityMaterial.renderQueue = 3000;
  158. // 设置纹理过滤
  159. if (highQualityMaterial.mainTexture != null)
  160. {
  161. highQualityMaterial.mainTexture.filterMode = preferredFilterMode;
  162. }
  163. Debug.Log("已创建高质量字体材质");
  164. }
  165. [ContextMenu("优化字体设置")]
  166. public void OptimizeFontSettings()
  167. {
  168. // 查找所有字体资源
  169. Font[] fonts = Resources.FindObjectsOfTypeAll<Font>();
  170. foreach (Font font in fonts)
  171. {
  172. if (font != null)
  173. {
  174. // 注意:字体属性需要在Unity编辑器的字体导入设置中手动调整
  175. if (fontTextureSize > 0)
  176. {
  177. Debug.Log($"建议将字体 {font.name} 的纹理大小设置为 {fontTextureSize}");
  178. }
  179. }
  180. }
  181. Debug.Log($"已检查 {fonts.Length} 个字体设置");
  182. }
  183. [ContextMenu("检查文字质量")]
  184. public void CheckTextQuality()
  185. {
  186. Debug.Log("=== 文字质量检查报告 ===");
  187. Debug.Log($"屏幕分辨率: {Screen.currentResolution.width}x{Screen.currentResolution.height}");
  188. Debug.Log($"DPI: {Screen.dpi}");
  189. Debug.Log($"抗锯齿级别: {QualitySettings.antiAliasing}");
  190. Debug.Log($"纹理质量: {QualitySettings.masterTextureLimit}");
  191. Debug.Log($"各向异性过滤: {QualitySettings.anisotropicFiltering}");
  192. // 检查场景中的文字组件
  193. Text[] texts = FindObjectsOfType<Text>();
  194. TextMeshProUGUI[] tmpTexts = FindObjectsOfType<TextMeshProUGUI>();
  195. Debug.Log($"场景中Text组件数量: {texts.Length}");
  196. Debug.Log($"场景中TextMeshPro组件数量: {tmpTexts.Length}");
  197. // 检查Canvas设置
  198. Canvas[] canvases = FindObjectsOfType<Canvas>();
  199. Debug.Log($"场景中Canvas数量: {canvases.Length}");
  200. foreach (Canvas canvas in canvases)
  201. {
  202. Debug.Log($"Canvas '{canvas.name}' 渲染模式: {canvas.renderMode}");
  203. CanvasScaler scaler = canvas.GetComponent<CanvasScaler>();
  204. if (scaler != null)
  205. {
  206. Debug.Log($"Canvas '{canvas.name}' 缩放模式: {scaler.uiScaleMode}");
  207. }
  208. }
  209. }
  210. [ContextMenu("应用像素完美模式")]
  211. public void ApplyPixelPerfectMode()
  212. {
  213. if (!usePixelPerfect) return;
  214. // 设置像素完美渲染
  215. if (mainCamera != null)
  216. {
  217. mainCamera.orthographic = true;
  218. mainCamera.orthographicSize = Screen.height / 2f / 100f; // 假设100像素 = 1单位
  219. }
  220. // 设置Canvas为像素完美
  221. Canvas[] canvases = FindObjectsOfType<Canvas>();
  222. foreach (Canvas canvas in canvases)
  223. {
  224. CanvasScaler scaler = canvas.GetComponent<CanvasScaler>();
  225. if (scaler != null)
  226. {
  227. scaler.uiScaleMode = CanvasScaler.ScaleMode.ConstantPixelSize;
  228. scaler.scaleFactor = 1.0f;
  229. }
  230. }
  231. Debug.Log("已应用像素完美模式");
  232. }
  233. // 在Inspector中实时预览
  234. private void OnValidate()
  235. {
  236. if (Application.isPlaying)
  237. {
  238. // 实时应用某些设置
  239. if (enableMSAA)
  240. {
  241. QualitySettings.antiAliasing = 4;
  242. }
  243. }
  244. }
  245. }