SpriteShape.cs 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. using System;
  2. using System.Collections.Generic;
  3. namespace UnityEngine.U2D
  4. {
  5. public enum ShapeTangentMode
  6. {
  7. Linear = 0,
  8. Continuous = 1,
  9. Broken = 2,
  10. };
  11. public enum CornerType
  12. {
  13. OuterTopLeft,
  14. OuterTopRight,
  15. OuterBottomLeft,
  16. OuterBottomRight,
  17. InnerTopLeft,
  18. InnerTopRight,
  19. InnerBottomLeft,
  20. InnerBottomRight,
  21. };
  22. public enum QualityDetail
  23. {
  24. High = 16,
  25. Mid = 8,
  26. Low = 4
  27. }
  28. public enum Corner
  29. {
  30. Disable = 0,
  31. Automatic = 1,
  32. Stretched = 2,
  33. }
  34. [System.Serializable]
  35. public class SplineControlPoint
  36. {
  37. public Vector3 position;
  38. public Vector3 leftTangent;
  39. public Vector3 rightTangent;
  40. public ShapeTangentMode mode;
  41. public float height = 1f;
  42. public float bevelCutoff;
  43. public float bevelSize;
  44. public int spriteIndex;
  45. public bool corner;
  46. [SerializeField]
  47. Corner m_CornerMode;
  48. public Corner cornerMode
  49. {
  50. get => m_CornerMode;
  51. set => m_CornerMode = value;
  52. }
  53. public override int GetHashCode()
  54. {
  55. return ((int)position.x).GetHashCode() ^ ((int)position.y).GetHashCode() ^ position.GetHashCode() ^
  56. (leftTangent.GetHashCode() << 2) ^ (rightTangent.GetHashCode() >> 2) ^ ((int)mode).GetHashCode() ^
  57. height.GetHashCode() ^ spriteIndex.GetHashCode() ^ corner.GetHashCode() ^ (m_CornerMode.GetHashCode() << 2);
  58. }
  59. }
  60. [System.Serializable]
  61. public class AngleRange : ICloneable
  62. {
  63. public float start
  64. {
  65. get { return m_Start; }
  66. set { m_Start = value; }
  67. }
  68. public float end
  69. {
  70. get { return m_End; }
  71. set { m_End = value; }
  72. }
  73. public int order
  74. {
  75. get { return m_Order; }
  76. set { m_Order = value; }
  77. }
  78. public List<Sprite> sprites
  79. {
  80. get { return m_Sprites; }
  81. set { m_Sprites = value; }
  82. }
  83. [SerializeField]
  84. float m_Start;
  85. [SerializeField]
  86. float m_End;
  87. [SerializeField]
  88. int m_Order;
  89. [SerializeField]
  90. List<Sprite> m_Sprites = new List<Sprite>();
  91. public object Clone()
  92. {
  93. AngleRange clone = this.MemberwiseClone() as AngleRange;
  94. clone.sprites = new List<Sprite>(clone.sprites);
  95. return clone;
  96. }
  97. public override bool Equals(object obj)
  98. {
  99. var other = obj as AngleRange;
  100. if (other == null)
  101. return false;
  102. bool equals = start.Equals(other.start) && end.Equals(other.end) && order.Equals(other.order);
  103. if (!equals)
  104. return false;
  105. if (sprites.Count != other.sprites.Count)
  106. return false;
  107. for (int i = 0; i < sprites.Count; ++i)
  108. if (sprites[i] != other.sprites[i])
  109. return false;
  110. return true;
  111. }
  112. public override int GetHashCode()
  113. {
  114. int hashCode = start.GetHashCode() ^ end.GetHashCode() ^ order.GetHashCode();
  115. if (sprites != null)
  116. {
  117. for (int i = 0; i < sprites.Count; i++)
  118. {
  119. Sprite sprite = sprites[i];
  120. if (sprite)
  121. hashCode = hashCode * 16777619 ^ (sprite.GetHashCode() + i);
  122. }
  123. }
  124. return hashCode;
  125. }
  126. }
  127. [System.Serializable]
  128. public class CornerSprite : ICloneable
  129. {
  130. public CornerType cornerType
  131. {
  132. get { return m_CornerType; }
  133. set { m_CornerType = value; }
  134. }
  135. public List<Sprite> sprites
  136. {
  137. get { return m_Sprites; }
  138. set { m_Sprites = value; }
  139. }
  140. [SerializeField]
  141. CornerType m_CornerType; ///< Set Corner type. enum { OuterTopLeft = 0, OuterTopRight = 1, OuterBottomLeft = 2, OuterBottomRight = 3, InnerTopLeft = 4, InnerTopRight = 5, InnerBottomLeft = 6, InnerBottomRight = 7 }
  142. [SerializeField]
  143. List<Sprite> m_Sprites;
  144. public object Clone()
  145. {
  146. CornerSprite clone = this.MemberwiseClone() as CornerSprite;
  147. clone.sprites = new List<Sprite>(clone.sprites);
  148. return clone;
  149. }
  150. public override bool Equals(object obj)
  151. {
  152. var other = obj as CornerSprite;
  153. if (other == null)
  154. return false;
  155. if (!cornerType.Equals(other.cornerType))
  156. return false;
  157. if (sprites.Count != other.sprites.Count)
  158. return false;
  159. for (int i = 0; i < sprites.Count; ++i)
  160. if (sprites[i] != other.sprites[i])
  161. return false;
  162. return true;
  163. }
  164. public override int GetHashCode()
  165. {
  166. int hashCode = cornerType.GetHashCode();
  167. if (sprites != null)
  168. {
  169. for (int i = 0; i < sprites.Count; i++)
  170. {
  171. Sprite sprite = sprites[i];
  172. if (sprite)
  173. {
  174. hashCode ^= (i + 1);
  175. hashCode ^= sprite.GetHashCode();
  176. }
  177. }
  178. }
  179. return hashCode;
  180. }
  181. }
  182. [HelpURLAttribute("https://docs.unity3d.com/Packages/com.unity.2d.spriteshape@latest/index.html?subfolder=/manual/SSProfile.html")]
  183. public class SpriteShape : ScriptableObject
  184. {
  185. public List<AngleRange> angleRanges
  186. {
  187. get { return m_Angles; }
  188. set { m_Angles = value; }
  189. }
  190. public Texture2D fillTexture
  191. {
  192. get { return m_FillTexture; }
  193. set { m_FillTexture = value; }
  194. }
  195. public List<CornerSprite> cornerSprites
  196. {
  197. get { return m_CornerSprites; }
  198. set { m_CornerSprites = value; }
  199. }
  200. public float fillOffset
  201. {
  202. get { return m_FillOffset; }
  203. set { m_FillOffset = value; }
  204. }
  205. public bool useSpriteBorders
  206. {
  207. get { return m_UseSpriteBorders; }
  208. set { m_UseSpriteBorders = value; }
  209. }
  210. [SerializeField]
  211. List<AngleRange> m_Angles = new List<AngleRange>();
  212. [SerializeField]
  213. Texture2D m_FillTexture;
  214. [SerializeField]
  215. List<CornerSprite> m_CornerSprites = new List<CornerSprite>();
  216. [SerializeField]
  217. float m_FillOffset;
  218. [SerializeField]
  219. bool m_UseSpriteBorders = true;
  220. private CornerSprite GetCornerSprite(CornerType cornerType)
  221. {
  222. var cornerSprite = new CornerSprite();
  223. cornerSprite.cornerType = cornerType;
  224. cornerSprite.sprites = new List<Sprite>();
  225. cornerSprite.sprites.Insert(0, null);
  226. return cornerSprite;
  227. }
  228. void ResetCornerList()
  229. {
  230. m_CornerSprites.Clear();
  231. m_CornerSprites.Insert(0, GetCornerSprite(CornerType.OuterTopLeft));
  232. m_CornerSprites.Insert(1, GetCornerSprite(CornerType.OuterTopRight));
  233. m_CornerSprites.Insert(2, GetCornerSprite(CornerType.OuterBottomLeft));
  234. m_CornerSprites.Insert(3, GetCornerSprite(CornerType.OuterBottomRight));
  235. m_CornerSprites.Insert(4, GetCornerSprite(CornerType.InnerTopLeft));
  236. m_CornerSprites.Insert(5, GetCornerSprite(CornerType.InnerTopRight));
  237. m_CornerSprites.Insert(6, GetCornerSprite(CornerType.InnerBottomLeft));
  238. m_CornerSprites.Insert(7, GetCornerSprite(CornerType.InnerBottomRight));
  239. }
  240. void OnValidate()
  241. {
  242. if (m_CornerSprites.Count != 8)
  243. ResetCornerList();
  244. }
  245. void Reset()
  246. {
  247. m_Angles.Clear();
  248. ResetCornerList();
  249. }
  250. internal static int GetSpriteShapeHashCode(SpriteShape spriteShape)
  251. {
  252. // useSpriteBorders, fillOffset and fillTexture are hashChecked elsewhere.
  253. unchecked
  254. {
  255. int hashCode = (int)2166136261;
  256. hashCode = hashCode * 16777619 ^ spriteShape.angleRanges.Count;
  257. for (int i = 0; i < spriteShape.angleRanges.Count; ++i)
  258. {
  259. hashCode = hashCode * 16777619 ^ (spriteShape.angleRanges[i].GetHashCode() + i);
  260. }
  261. hashCode = hashCode * 16777619 ^ spriteShape.cornerSprites.Count;
  262. for (int i = 0; i < spriteShape.cornerSprites.Count; ++i)
  263. {
  264. hashCode = hashCode * 16777619 ^ (spriteShape.cornerSprites[i].GetHashCode() + i);
  265. }
  266. return hashCode;
  267. }
  268. }
  269. }
  270. }