DOTweenModuleUnityVersion.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. // Author: Daniele Giardini - http://www.demigiant.com
  2. // Created: 2018/07/13
  3. using System;
  4. using UnityEngine;
  5. using DG.Tweening.Core;
  6. using DG.Tweening.Plugins.Options;
  7. //#if UNITY_2018_1_OR_NEWER && (NET_4_6 || NET_STANDARD_2_0)
  8. //using Task = System.Threading.Tasks.Task;
  9. //#endif
  10. #pragma warning disable 1591
  11. namespace DG.Tweening
  12. {
  13. /// <summary>
  14. /// Shortcuts/functions that are not strictly related to specific Modules
  15. /// but are available only on some Unity versions
  16. /// </summary>
  17. public static class DOTweenModuleUnityVersion
  18. {
  19. #region Material
  20. /// <summary>Tweens a Material's color using the given gradient
  21. /// (NOTE 1: only uses the colors of the gradient, not the alphas - NOTE 2: creates a Sequence, not a Tweener).
  22. /// Also stores the image as the tween's target so it can be used for filtered operations</summary>
  23. /// <param name="gradient">The gradient to use</param><param name="duration">The duration of the tween</param>
  24. public static Sequence DOGradientColor(this Material target, Gradient gradient, float duration)
  25. {
  26. Sequence s = DOTween.Sequence();
  27. GradientColorKey[] colors = gradient.colorKeys;
  28. int len = colors.Length;
  29. for (int i = 0; i < len; ++i) {
  30. GradientColorKey c = colors[i];
  31. if (i == 0 && c.time <= 0) {
  32. target.color = c.color;
  33. continue;
  34. }
  35. float colorDuration = i == len - 1
  36. ? duration - s.Duration(false) // Verifies that total duration is correct
  37. : duration * (i == 0 ? c.time : c.time - colors[i - 1].time);
  38. s.Append(target.DOColor(c.color, colorDuration).SetEase(Ease.Linear));
  39. }
  40. s.SetTarget(target);
  41. return s;
  42. }
  43. /// <summary>Tweens a Material's named color property using the given gradient
  44. /// (NOTE 1: only uses the colors of the gradient, not the alphas - NOTE 2: creates a Sequence, not a Tweener).
  45. /// Also stores the image as the tween's target so it can be used for filtered operations</summary>
  46. /// <param name="gradient">The gradient to use</param>
  47. /// <param name="property">The name of the material property to tween (like _Tint or _SpecColor)</param>
  48. /// <param name="duration">The duration of the tween</param>
  49. public static Sequence DOGradientColor(this Material target, Gradient gradient, string property, float duration)
  50. {
  51. Sequence s = DOTween.Sequence();
  52. GradientColorKey[] colors = gradient.colorKeys;
  53. int len = colors.Length;
  54. for (int i = 0; i < len; ++i) {
  55. GradientColorKey c = colors[i];
  56. if (i == 0 && c.time <= 0) {
  57. target.SetColor(property, c.color);
  58. continue;
  59. }
  60. float colorDuration = i == len - 1
  61. ? duration - s.Duration(false) // Verifies that total duration is correct
  62. : duration * (i == 0 ? c.time : c.time - colors[i - 1].time);
  63. s.Append(target.DOColor(c.color, property, colorDuration).SetEase(Ease.Linear));
  64. }
  65. s.SetTarget(target);
  66. return s;
  67. }
  68. #endregion
  69. #region CustomYieldInstructions
  70. /// <summary>
  71. /// Returns a <see cref="CustomYieldInstruction"/> that waits until the tween is killed or complete.
  72. /// It can be used inside a coroutine as a yield.
  73. /// <para>Example usage:</para><code>yield return myTween.WaitForCompletion(true);</code>
  74. /// </summary>
  75. public static CustomYieldInstruction WaitForCompletion(this Tween t, bool returnCustomYieldInstruction)
  76. {
  77. if (!t.active) {
  78. if (Debugger.logPriority > 0) Debugger.LogInvalidTween(t);
  79. return null;
  80. }
  81. return new DOTweenCYInstruction.WaitForCompletion(t);
  82. }
  83. /// <summary>
  84. /// Returns a <see cref="CustomYieldInstruction"/> that waits until the tween is killed or rewinded.
  85. /// It can be used inside a coroutine as a yield.
  86. /// <para>Example usage:</para><code>yield return myTween.WaitForRewind();</code>
  87. /// </summary>
  88. public static CustomYieldInstruction WaitForRewind(this Tween t, bool returnCustomYieldInstruction)
  89. {
  90. if (!t.active) {
  91. if (Debugger.logPriority > 0) Debugger.LogInvalidTween(t);
  92. return null;
  93. }
  94. return new DOTweenCYInstruction.WaitForRewind(t);
  95. }
  96. /// <summary>
  97. /// Returns a <see cref="CustomYieldInstruction"/> that waits until the tween is killed.
  98. /// It can be used inside a coroutine as a yield.
  99. /// <para>Example usage:</para><code>yield return myTween.WaitForKill();</code>
  100. /// </summary>
  101. public static CustomYieldInstruction WaitForKill(this Tween t, bool returnCustomYieldInstruction)
  102. {
  103. if (!t.active) {
  104. if (Debugger.logPriority > 0) Debugger.LogInvalidTween(t);
  105. return null;
  106. }
  107. return new DOTweenCYInstruction.WaitForKill(t);
  108. }
  109. /// <summary>
  110. /// Returns a <see cref="CustomYieldInstruction"/> that waits until the tween is killed or has gone through the given amount of loops.
  111. /// It can be used inside a coroutine as a yield.
  112. /// <para>Example usage:</para><code>yield return myTween.WaitForElapsedLoops(2);</code>
  113. /// </summary>
  114. /// <param name="elapsedLoops">Elapsed loops to wait for</param>
  115. public static CustomYieldInstruction WaitForElapsedLoops(this Tween t, int elapsedLoops, bool returnCustomYieldInstruction)
  116. {
  117. if (!t.active) {
  118. if (Debugger.logPriority > 0) Debugger.LogInvalidTween(t);
  119. return null;
  120. }
  121. return new DOTweenCYInstruction.WaitForElapsedLoops(t, elapsedLoops);
  122. }
  123. /// <summary>
  124. /// Returns a <see cref="CustomYieldInstruction"/> that waits until the tween is killed
  125. /// or has reached the given time position (loops included, delays excluded).
  126. /// It can be used inside a coroutine as a yield.
  127. /// <para>Example usage:</para><code>yield return myTween.WaitForPosition(2.5f);</code>
  128. /// </summary>
  129. /// <param name="position">Position (loops included, delays excluded) to wait for</param>
  130. public static CustomYieldInstruction WaitForPosition(this Tween t, float position, bool returnCustomYieldInstruction)
  131. {
  132. if (!t.active) {
  133. if (Debugger.logPriority > 0) Debugger.LogInvalidTween(t);
  134. return null;
  135. }
  136. return new DOTweenCYInstruction.WaitForPosition(t, position);
  137. }
  138. /// <summary>
  139. /// Returns a <see cref="CustomYieldInstruction"/> that waits until the tween is killed or started
  140. /// (meaning when the tween is set in a playing state the first time, after any eventual delay).
  141. /// It can be used inside a coroutine as a yield.
  142. /// <para>Example usage:</para><code>yield return myTween.WaitForStart();</code>
  143. /// </summary>
  144. public static CustomYieldInstruction WaitForStart(this Tween t, bool returnCustomYieldInstruction)
  145. {
  146. if (!t.active) {
  147. if (Debugger.logPriority > 0) Debugger.LogInvalidTween(t);
  148. return null;
  149. }
  150. return new DOTweenCYInstruction.WaitForStart(t);
  151. }
  152. #endregion
  153. #if UNITY_2018_1_OR_NEWER
  154. #region Unity 2018.1 or Newer
  155. #region Material
  156. /// <summary>Tweens a Material's named texture offset property with the given ID to the given value.
  157. /// Also stores the material as the tween's target so it can be used for filtered operations</summary>
  158. /// <param name="endValue">The end value to reach</param>
  159. /// <param name="propertyID">The ID of the material property to tween (also called nameID in Unity's manual)</param>
  160. /// <param name="duration">The duration of the tween</param>
  161. public static TweenerCore<Vector2, Vector2, VectorOptions> DOOffset(this Material target, Vector2 endValue, int propertyID, float duration)
  162. {
  163. if (!target.HasProperty(propertyID)) {
  164. if (Debugger.logPriority > 0) Debugger.LogMissingMaterialProperty(propertyID);
  165. return null;
  166. }
  167. TweenerCore<Vector2, Vector2, VectorOptions> t = DOTween.To(() => target.GetTextureOffset(propertyID), x => target.SetTextureOffset(propertyID, x), endValue, duration);
  168. t.SetTarget(target);
  169. return t;
  170. }
  171. /// <summary>Tweens a Material's named texture scale property with the given ID to the given value.
  172. /// Also stores the material as the tween's target so it can be used for filtered operations</summary>
  173. /// <param name="endValue">The end value to reach</param>
  174. /// <param name="propertyID">The ID of the material property to tween (also called nameID in Unity's manual)</param>
  175. /// <param name="duration">The duration of the tween</param>
  176. public static TweenerCore<Vector2, Vector2, VectorOptions> DOTiling(this Material target, Vector2 endValue, int propertyID, float duration)
  177. {
  178. if (!target.HasProperty(propertyID)) {
  179. if (Debugger.logPriority > 0) Debugger.LogMissingMaterialProperty(propertyID);
  180. return null;
  181. }
  182. TweenerCore<Vector2, Vector2, VectorOptions> t = DOTween.To(() => target.GetTextureScale(propertyID), x => target.SetTextureScale(propertyID, x), endValue, duration);
  183. t.SetTarget(target);
  184. return t;
  185. }
  186. #endregion
  187. #region .NET 4.6 or Newer
  188. #if UNITY_2018_1_OR_NEWER && (NET_4_6 || NET_STANDARD_2_0)
  189. #region Async Instructions
  190. /// <summary>
  191. /// Returns an async <see cref="System.Threading.Tasks.Task"/> that waits until the tween is killed or complete.
  192. /// It can be used inside an async operation.
  193. /// <para>Example usage:</para><code>await myTween.WaitForCompletion();</code>
  194. /// </summary>
  195. public static async System.Threading.Tasks.Task AsyncWaitForCompletion(this Tween t)
  196. {
  197. if (!t.active) {
  198. if (Debugger.logPriority > 0) Debugger.LogInvalidTween(t);
  199. return;
  200. }
  201. while (t.active && !t.IsComplete()) await System.Threading.Tasks.Task.Yield();
  202. }
  203. /// <summary>
  204. /// Returns an async <see cref="System.Threading.Tasks.Task"/> that waits until the tween is killed or rewinded.
  205. /// It can be used inside an async operation.
  206. /// <para>Example usage:</para><code>await myTween.AsyncWaitForRewind();</code>
  207. /// </summary>
  208. public static async System.Threading.Tasks.Task AsyncWaitForRewind(this Tween t)
  209. {
  210. if (!t.active) {
  211. if (Debugger.logPriority > 0) Debugger.LogInvalidTween(t);
  212. return;
  213. }
  214. while (t.active && (!t.playedOnce || t.position * (t.CompletedLoops() + 1) > 0)) await System.Threading.Tasks.Task.Yield();
  215. }
  216. /// <summary>
  217. /// Returns an async <see cref="System.Threading.Tasks.Task"/> that waits until the tween is killed.
  218. /// It can be used inside an async operation.
  219. /// <para>Example usage:</para><code>await myTween.AsyncWaitForKill();</code>
  220. /// </summary>
  221. public static async System.Threading.Tasks.Task AsyncWaitForKill(this Tween t)
  222. {
  223. if (!t.active) {
  224. if (Debugger.logPriority > 0) Debugger.LogInvalidTween(t);
  225. return;
  226. }
  227. while (t.active) await System.Threading.Tasks.Task.Yield();
  228. }
  229. /// <summary>
  230. /// Returns an async <see cref="System.Threading.Tasks.Task"/> that waits until the tween is killed or has gone through the given amount of loops.
  231. /// It can be used inside an async operation.
  232. /// <para>Example usage:</para><code>await myTween.AsyncWaitForElapsedLoops();</code>
  233. /// </summary>
  234. /// <param name="elapsedLoops">Elapsed loops to wait for</param>
  235. public static async System.Threading.Tasks.Task AsyncWaitForElapsedLoops(this Tween t, int elapsedLoops)
  236. {
  237. if (!t.active) {
  238. if (Debugger.logPriority > 0) Debugger.LogInvalidTween(t);
  239. return;
  240. }
  241. while (t.active && t.CompletedLoops() < elapsedLoops) await System.Threading.Tasks.Task.Yield();
  242. }
  243. /// <summary>
  244. /// Returns an async <see cref="System.Threading.Tasks.Task"/> that waits until the tween is killed or started
  245. /// (meaning when the tween is set in a playing state the first time, after any eventual delay).
  246. /// It can be used inside an async operation.
  247. /// <para>Example usage:</para><code>await myTween.AsyncWaitForPosition();</code>
  248. /// </summary>
  249. /// <param name="position">Position (loops included, delays excluded) to wait for</param>
  250. public static async System.Threading.Tasks.Task AsyncWaitForPosition(this Tween t, float position)
  251. {
  252. if (!t.active) {
  253. if (Debugger.logPriority > 0) Debugger.LogInvalidTween(t);
  254. return;
  255. }
  256. while (t.active && t.position * (t.CompletedLoops() + 1) < position) await System.Threading.Tasks.Task.Yield();
  257. }
  258. /// <summary>
  259. /// Returns an async <see cref="System.Threading.Tasks.Task"/> that waits until the tween is killed.
  260. /// It can be used inside an async operation.
  261. /// <para>Example usage:</para><code>await myTween.AsyncWaitForKill();</code>
  262. /// </summary>
  263. public static async System.Threading.Tasks.Task AsyncWaitForStart(this Tween t)
  264. {
  265. if (!t.active) {
  266. if (Debugger.logPriority > 0) Debugger.LogInvalidTween(t);
  267. return;
  268. }
  269. while (t.active && !t.playedOnce) await System.Threading.Tasks.Task.Yield();
  270. }
  271. #endregion
  272. #endif
  273. #endregion
  274. #endregion
  275. #endif
  276. }
  277. // █████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
  278. // ███ CLASSES █████████████████████████████████████████████████████████████████████████████████████████████████████████
  279. // █████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
  280. public static class DOTweenCYInstruction
  281. {
  282. public class WaitForCompletion : CustomYieldInstruction
  283. {
  284. public override bool keepWaiting { get {
  285. return t.active && !t.IsComplete();
  286. }}
  287. readonly Tween t;
  288. public WaitForCompletion(Tween tween)
  289. {
  290. t = tween;
  291. }
  292. }
  293. public class WaitForRewind : CustomYieldInstruction
  294. {
  295. public override bool keepWaiting { get {
  296. return t.active && (!t.playedOnce || t.position * (t.CompletedLoops() + 1) > 0);
  297. }}
  298. readonly Tween t;
  299. public WaitForRewind(Tween tween)
  300. {
  301. t = tween;
  302. }
  303. }
  304. public class WaitForKill : CustomYieldInstruction
  305. {
  306. public override bool keepWaiting { get {
  307. return t.active;
  308. }}
  309. readonly Tween t;
  310. public WaitForKill(Tween tween)
  311. {
  312. t = tween;
  313. }
  314. }
  315. public class WaitForElapsedLoops : CustomYieldInstruction
  316. {
  317. public override bool keepWaiting { get {
  318. return t.active && t.CompletedLoops() < elapsedLoops;
  319. }}
  320. readonly Tween t;
  321. readonly int elapsedLoops;
  322. public WaitForElapsedLoops(Tween tween, int elapsedLoops)
  323. {
  324. t = tween;
  325. this.elapsedLoops = elapsedLoops;
  326. }
  327. }
  328. public class WaitForPosition : CustomYieldInstruction
  329. {
  330. public override bool keepWaiting { get {
  331. return t.active && t.position * (t.CompletedLoops() + 1) < position;
  332. }}
  333. readonly Tween t;
  334. readonly float position;
  335. public WaitForPosition(Tween tween, float position)
  336. {
  337. t = tween;
  338. this.position = position;
  339. }
  340. }
  341. public class WaitForStart : CustomYieldInstruction
  342. {
  343. public override bool keepWaiting { get {
  344. return t.active && !t.playedOnce;
  345. }}
  346. readonly Tween t;
  347. public WaitForStart(Tween tween)
  348. {
  349. t = tween;
  350. }
  351. }
  352. }
  353. }