ConvertMaskMenu.cs 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. using System;
  2. using System.IO;
  3. using System.Linq;
  4. using UnityEditor;
  5. using UnityEngine;
  6. using UnityEngine.Assertions;
  7. using UnityEngine.UI;
  8. namespace SoftMasking.Editor {
  9. public static class ConvertMaskMenu {
  10. [MenuItem("Tools/Soft Mask/Convert Mask to Soft Mask")]
  11. public static void ConvertMenu() {
  12. var undoGroup = Undo.GetCurrentGroup();
  13. try {
  14. Convert();
  15. } catch (UnsupportedRawImageTextureType ex) {
  16. EditorUtility.DisplayDialog(
  17. "Soft Mask",
  18. string.Format(
  19. "Unable to convert object '{0}' to Soft Mask. It's Raw Image component has Texture of an unsupported type: {1}.",
  20. ex.objectBeingConverted.name,
  21. ex.unsupportedTexture.GetType().Name),
  22. "OK");
  23. Undo.RevertAllDownToGroup(undoGroup);
  24. } catch (UnsupportedImageType ex) {
  25. EditorUtility.DisplayDialog(
  26. "Soft Mask",
  27. string.Format(
  28. "Unable to convert object '{0}' to SoftMask. It's Image component has unsupported type: {1}.",
  29. ex.objectBeingConverted.name,
  30. ex.unsupportedType),
  31. "OK");
  32. Undo.RevertAllDownToGroup(undoGroup);
  33. }
  34. }
  35. [MenuItem("Tools/Soft Mask/Convert Mask to Soft Mask", validate = true)]
  36. public static bool CanConvertMenu() {
  37. return CanConvert();
  38. }
  39. public static void Convert() {
  40. Assert.IsTrue(CanConvert());
  41. Undo.IncrementCurrentGroup();
  42. Undo.SetCurrentGroupName("Convert Mask to Soft Mask");
  43. var selectedTransforms = Selection.GetTransforms(SelectionMode.Editable);
  44. foreach (var transform in selectedTransforms)
  45. Convert(transform.gameObject);
  46. }
  47. public static bool CanConvert() {
  48. var selectedTransforms = Selection.GetTransforms(SelectionMode.Editable);
  49. return selectedTransforms.Any()
  50. && selectedTransforms.All(t => IsConvertibleMask(t.gameObject));
  51. }
  52. static bool IsConvertibleMask(GameObject gameObject) {
  53. var mask = gameObject.GetComponent<Mask>();
  54. var graphic = gameObject.GetComponent<Graphic>();
  55. return mask
  56. && graphic
  57. && (graphic is Image || graphic is RawImage);
  58. }
  59. static void Convert(GameObject gameObject) {
  60. Assert.IsTrue(IsConvertibleMask(gameObject));
  61. DeepCheckConvertibility(gameObject);
  62. var mask = gameObject.GetComponent<Mask>();
  63. var softMask = Undo.AddComponent<SoftMask>(gameObject);
  64. var mayUseGraphic = MayUseGraphicSource(mask);
  65. if (mayUseGraphic) {
  66. softMask.source = SoftMask.MaskSource.Graphic;
  67. Undo.DestroyObjectImmediate(mask);
  68. } else {
  69. var graphic = gameObject.GetComponent<Graphic>();
  70. if (graphic is Image)
  71. SetUpFromImage(softMask, (Image)graphic);
  72. else if (graphic is RawImage)
  73. SetUpFromRawImage(softMask, (RawImage)graphic);
  74. else
  75. Debug.LogAssertionFormat("Converted Game Object should have an Image or Raw Image component");
  76. Undo.DestroyObjectImmediate(mask);
  77. if (!mask.showMaskGraphic)
  78. Undo.DestroyObjectImmediate(graphic);
  79. }
  80. }
  81. static void DeepCheckConvertibility(GameObject gameObject) {
  82. var rawImage = gameObject.GetComponent<RawImage>();
  83. if (rawImage) {
  84. var texture = rawImage.texture;
  85. if (texture && !(texture is Texture2D) && !(texture is RenderTexture))
  86. throw new UnsupportedRawImageTextureType(gameObject, texture);
  87. }
  88. var image = gameObject.GetComponent<Image>();
  89. if (image && !SoftMask.IsImageTypeSupported(image.type))
  90. throw new UnsupportedImageType(image.gameObject, image.type);
  91. }
  92. public class UnsupportedImageType : Exception {
  93. public UnsupportedImageType(GameObject objectBeingConverted, Image.Type unsupportedType) {
  94. this.objectBeingConverted = objectBeingConverted;
  95. this.unsupportedType = unsupportedType;
  96. }
  97. public GameObject objectBeingConverted { get; private set; }
  98. public Image.Type unsupportedType { get; private set; }
  99. }
  100. public class UnsupportedRawImageTextureType : Exception {
  101. public UnsupportedRawImageTextureType(GameObject objectBeingConverted, Texture unsupportedTexture) {
  102. this.objectBeingConverted = objectBeingConverted;
  103. this.unsupportedTexture = unsupportedTexture;
  104. }
  105. public GameObject objectBeingConverted { get; private set; }
  106. public Texture unsupportedTexture { get; private set; }
  107. }
  108. static bool MayUseGraphicSource(Mask mask) {
  109. var image = mask.GetComponent<Image>();
  110. var usesStandardUIMaskSprite = image && IsStandardUIMaskSprite(image.sprite);
  111. return mask.showMaskGraphic
  112. && !usesStandardUIMaskSprite;
  113. }
  114. static bool IsStandardUIMaskSprite(Sprite sprite) {
  115. return sprite == standardUIMaskSprite;
  116. }
  117. static Sprite SoftMaskCompatibleVersionOf(Sprite original) {
  118. return IsStandardUIMaskSprite(original)
  119. ? adaptedUIMaskSprite
  120. : original;
  121. }
  122. static void SetUpFromImage(SoftMask softMask, Image image) {
  123. Assert.IsTrue(SoftMask.IsImageTypeSupported(image.type));
  124. softMask.source = SoftMask.MaskSource.Sprite;
  125. softMask.sprite = SoftMaskCompatibleVersionOf(image.sprite);
  126. softMask.spriteBorderMode = SoftMask.ImageTypeToBorderMode(image.type);
  127. #if UNITY_2019_2_OR_NEWER
  128. softMask.spritePixelsPerUnitMultiplier = image.pixelsPerUnitMultiplier;
  129. #endif
  130. }
  131. static void SetUpFromRawImage(SoftMask softMask, RawImage rawImage) {
  132. softMask.source = SoftMask.MaskSource.Texture;
  133. var texture = rawImage.texture;
  134. if (texture)
  135. if (texture is Texture2D)
  136. softMask.texture = (Texture2D)texture;
  137. else if (texture is RenderTexture)
  138. softMask.renderTexture = (RenderTexture)texture;
  139. else
  140. Debug.LogAssertionFormat("Unsupported RawImage texture type: {0}", texture);
  141. softMask.textureUVRect = rawImage.uvRect;
  142. }
  143. static Sprite _standardUIMaskSprite;
  144. public static Sprite standardUIMaskSprite {
  145. get {
  146. if (!_standardUIMaskSprite)
  147. _standardUIMaskSprite = AssetDatabase.GetBuiltinExtraResource<Sprite>("UI/Skin/UIMask.psd");
  148. return _standardUIMaskSprite;
  149. }
  150. }
  151. static Sprite _adaptedUIMaskSprite;
  152. public static Sprite adaptedUIMaskSprite {
  153. get {
  154. if (!_adaptedUIMaskSprite)
  155. _adaptedUIMaskSprite =
  156. AssetDatabase.LoadAssetAtPath<Sprite>(
  157. Path.Combine(PackageResources.packagePath, "Sprites/UIMask-FullAlpha.png"));
  158. return _adaptedUIMaskSprite;
  159. }
  160. }
  161. }
  162. }