MaterialPropertyTransition.cs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using UnityEngine;
  7. using UnityEngine.UI;
  8. #pragma warning disable 0649 // disable "never assigned" warnings
  9. namespace TheraBytes.BetterUi
  10. {
  11. [Serializable]
  12. public class MaterialPropertyTransition : TransitionStateCollection<float>
  13. {
  14. static Dictionary<MaterialPropertyTransition, Coroutine> activeCoroutines = new Dictionary<MaterialPropertyTransition, Coroutine>();
  15. static List<MaterialPropertyTransition> keysToRemove = new List<MaterialPropertyTransition>();
  16. [Serializable]
  17. public class MaterialPropertyTransitionState : TransitionState
  18. {
  19. public MaterialPropertyTransitionState(string name, float stateObject)
  20. : base(name, stateObject)
  21. { }
  22. }
  23. public override UnityEngine.Object Target { get { return target; } }
  24. public float FadeDurtaion { get { return fadeDuration; } set { fadeDuration = value; } }
  25. public int PropertyIndex { get { return propertyIndex; } set { propertyIndex = value; } }
  26. [SerializeField]
  27. BetterImage target;
  28. [SerializeField]
  29. float fadeDuration = 0.1f;
  30. [SerializeField]
  31. List<MaterialPropertyTransitionState> states = new List<MaterialPropertyTransitionState>();
  32. [SerializeField]
  33. int propertyIndex;
  34. public MaterialPropertyTransition(params string[] stateNames)
  35. : base(stateNames)
  36. {
  37. }
  38. protected override void ApplyState(TransitionState state, bool instant)
  39. {
  40. if (this.Target == null)
  41. return;
  42. if (!(Application.isPlaying))
  43. {
  44. instant = true;
  45. }
  46. float start = target.GetMaterialPropertyValue(propertyIndex);
  47. CrossFadeProperty(start, state.StateObject, (instant) ? 0 : fadeDuration);
  48. }
  49. internal override void AddStateObject(string stateName)
  50. {
  51. var obj = new MaterialPropertyTransitionState(stateName, 1f);
  52. this.states.Add(obj);
  53. }
  54. protected override IEnumerable<TransitionState> GetTransitionStates()
  55. {
  56. foreach (var s in states)
  57. yield return s;
  58. }
  59. void CrossFadeProperty(float startValue, float targetValue, float duration)
  60. {
  61. // Stop clashing coroutines
  62. foreach (var key in activeCoroutines.Keys)
  63. {
  64. if (key.target == this.target && key.propertyIndex == this.propertyIndex)
  65. {
  66. if(key.target != null)
  67. key.target.StopCoroutine(activeCoroutines[key]);
  68. keysToRemove.Add(key);
  69. }
  70. }
  71. foreach (var key in keysToRemove)
  72. {
  73. activeCoroutines.Remove(key);
  74. }
  75. keysToRemove.Clear();
  76. // trigger value changes
  77. if (duration == 0 || !target.enabled || !target.gameObject.activeInHierarchy)
  78. {
  79. target.SetMaterialProperty(propertyIndex, targetValue);
  80. }
  81. else
  82. {
  83. Coroutine coroutine = target.StartCoroutine(CoCrossFadeProperty(startValue, targetValue, duration));
  84. activeCoroutines.Add(this, coroutine);
  85. }
  86. }
  87. private IEnumerator CoCrossFadeProperty(float startValue, float targetValue, float duration)
  88. {
  89. // animate
  90. float startTime = Time.unscaledTime;
  91. float endTime = startTime + duration;
  92. while(Time.unscaledTime < endTime)
  93. {
  94. float amount = (Time.unscaledTime - startTime) / duration;
  95. float value = Mathf.Lerp(startValue, targetValue, amount);
  96. target.SetMaterialProperty(propertyIndex, value);
  97. yield return null;
  98. }
  99. target.SetMaterialProperty(propertyIndex, targetValue);
  100. }
  101. internal override void SortStates(string[] sortedOrder)
  102. {
  103. base.SortStatesLogic(states, sortedOrder);
  104. }
  105. }
  106. }