SRRetinaScaler.cs 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. namespace SRF.UI
  2. {
  3. using Internal;
  4. using UnityEngine;
  5. using UnityEngine.UI;
  6. /// <summary>
  7. /// Detects when a screen dpi exceeds what the developer considers
  8. /// a "retina" level display, and scales the canvas accordingly.
  9. /// </summary>
  10. [RequireComponent(typeof (CanvasScaler))]
  11. [AddComponentMenu(ComponentMenuPaths.RetinaScaler)]
  12. public class SRRetinaScaler : SRMonoBehaviour
  13. {
  14. [SerializeField] private bool _disablePixelPerfect = false;
  15. [SerializeField] private int _designDpi = 120;
  16. private void Start()
  17. {
  18. ApplyScaling();
  19. }
  20. private void ApplyScaling()
  21. {
  22. var dpi = Screen.dpi;
  23. _lastDpi = dpi;
  24. if (dpi <= 0)
  25. {
  26. return;
  27. }
  28. #if !UNITY_EDITOR && UNITY_IOS
  29. // No iOS device has had low dpi for many years - Unity must be reporting it wrong.
  30. if(dpi < 120)
  31. {
  32. dpi = 321;
  33. }
  34. #endif
  35. var scaler = GetComponent<CanvasScaler>();
  36. scaler.uiScaleMode = CanvasScaler.ScaleMode.ConstantPixelSize;
  37. // Round scale to nearest 0.5
  38. float scale = dpi / _designDpi;
  39. scale = Mathf.Max(1, Mathf.Round(scale * 2) / 2.0f);
  40. scaler.scaleFactor = scale;
  41. if (_disablePixelPerfect)
  42. {
  43. GetComponent<Canvas>().pixelPerfect = false;
  44. }
  45. }
  46. private float _lastDpi;
  47. void Update()
  48. {
  49. if (Screen.dpi != _lastDpi)
  50. {
  51. ApplyScaling();
  52. }
  53. }
  54. }
  55. }