TextureSwapper.cs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /*
  2. E-mail : thomas.ir.rasor@gmail.com
  3. This script uses v1.5 Texture Swapping to swap between textures in a list.
  4. This script also includes functionality for toggling the material On and Off entirely,
  5. accessible through method calls or via the custom inspector.
  6. Methods in this script that should be called externally:
  7. SwapTexture()
  8. SwapTexture( int texture_id )
  9. ToggleState()
  10. */
  11. using UnityEngine;
  12. using System.Collections;
  13. using System.Collections.Generic;
  14. #if ( UNITY_EDITOR )
  15. using UnityEditor;
  16. using gui = UnityEngine.GUILayout;
  17. using egui = UnityEditor.EditorGUILayout;
  18. #endif
  19. namespace SSFS
  20. {
  21. public enum TextureSwapMode { Manual, Automatic, External }
  22. public class TextureSwapper : MonoBehaviour
  23. {
  24. public bool off = false;
  25. public TextureSwapMode mode = TextureSwapMode.Automatic;
  26. public bool remote = false;
  27. public Renderer targetRenderer = null;
  28. [System.NonSerialized]
  29. Renderer _r;
  30. public Renderer r { get { if ( remote ) _r = targetRenderer; if ( _r == null ) _r = GetComponent<Renderer>(); return _r; } }
  31. [System.NonSerialized]
  32. Material _m = null;
  33. public Material m
  34. {
  35. get
  36. {
  37. if ( _m == null && r != null && r.material != null )
  38. {
  39. _m = new Material( r.material );
  40. _m.name = "Temp SSFS Material";
  41. r.sharedMaterial = _m;
  42. }
  43. return _m;
  44. }
  45. }
  46. public List<Texture> textures = new List<Texture>();
  47. [Range( 0.5f , 5f )]
  48. public float transitionSpeed = 1f;
  49. public float transitionDelay = 5f;
  50. public KeyCode swapKey = KeyCode.Space;
  51. public bool randomOrder = false;
  52. bool _swapping = false;
  53. public bool swapping { get { return _swapping; } }
  54. float t = 0.1f;
  55. float tr = 1f;
  56. int i = 0;
  57. int ni = 0;
  58. public void Update()
  59. {
  60. t = Time.deltaTime * transitionSpeed;
  61. if ( mode == TextureSwapMode.Automatic )
  62. {
  63. tr -= t;
  64. if ( tr <= 0f )
  65. {
  66. SwapTexture();
  67. tr = transitionDelay;
  68. }
  69. }
  70. else if ( mode == TextureSwapMode.Manual && Input.GetKeyDown( swapKey ) )
  71. SwapTexture();
  72. }
  73. //Call this method from outside this script. Provide an ID to use a specific texture in textures.
  74. //If no ID or a negative id is provided, the script will choose either a random ID or the next ID in textures based on the randomOrder boolean.
  75. public void SwapTexture( int id = -1 )
  76. {
  77. if ( textures.Count < 2 ) return;
  78. int nextIndex = ( id < 0 ) ? ( randomOrder ? Random.Range( 0 , textures.Count ) : ( int )Mathf.Repeat( i + 1f , textures.Count ) ) : Mathf.Clamp( id , 0 , textures.Count );
  79. StartCoroutine( Transition( nextIndex ) );
  80. }
  81. public void ToggleState ()
  82. {
  83. StartCoroutine( Toggle() );
  84. }
  85. IEnumerator Transition( int nextIndex )
  86. {
  87. if ( m != null && textures.Count > 1 && !_swapping && !off )
  88. {
  89. _swapping = true;
  90. float p = 1f;
  91. m.SetFloat( "_Phase" , p );
  92. ni = nextIndex;
  93. m.SetTexture( "_MainTex" , textures[ i ] );
  94. m.SetTexture( "_MainTex2" , textures[ ni ] );
  95. m.EnableKeyword( "TEXTURE_SWAP" );
  96. while ( p > 0f )
  97. {
  98. m.SetFloat( "_Phase" , p );
  99. p -= t;
  100. yield return new WaitForEndOfFrame();
  101. }
  102. i = ni;
  103. m.SetTexture( "_MainTex" , textures[ i ] );
  104. m.SetFloat( "_Phase" , 1f );
  105. _swapping = false;
  106. }
  107. }
  108. IEnumerator Toggle ()
  109. {
  110. if ( m != null && !_swapping )
  111. {
  112. _swapping = true;
  113. m.SetTexture( "_MainTex2" , null );
  114. m.DisableKeyword( "TEXTURE_SWAP" );
  115. float p = off ? 0f : 1f;
  116. while ( off ? p < 1f : p > 0f )
  117. {
  118. p += off ? t : -t;
  119. m.SetFloat( "_Phase" , p );
  120. yield return new WaitForEndOfFrame();
  121. }
  122. off = !off;
  123. _swapping = false;
  124. }
  125. }
  126. }
  127. #if ( UNITY_EDITOR )
  128. [CustomEditor( typeof( TextureSwapper ) )]
  129. public class SSFS_TextureSwapper_Editor : Editor
  130. {
  131. TextureSwapper ts;
  132. GUIStyle _button = null;
  133. public GUIStyle button
  134. {
  135. get
  136. {
  137. if ( _button == null )
  138. {
  139. _button = new GUIStyle( GUI.skin.box );
  140. _button.fixedHeight = 20f;
  141. _button.margin = new RectOffset( 0 , 0 , 0 , 0 );
  142. }
  143. return _button;
  144. }
  145. }
  146. public override void OnInspectorGUI()
  147. {
  148. ts = ( TextureSwapper )target;
  149. egui.Space();
  150. gui.BeginHorizontal();
  151. ts.remote = egui.ToggleLeft( "External Renderer" , ts.remote );
  152. if ( ts.remote ) ts.targetRenderer = ( Renderer )egui.ObjectField( ts.targetRenderer , typeof( Renderer ) , true);
  153. gui.EndHorizontal();
  154. GUIContent mode = new GUIContent( "Mode" );
  155. switch(ts.mode)
  156. {
  157. case TextureSwapMode.Automatic:
  158. mode.tooltip = "Textures are swapped automatically over time.";
  159. break;
  160. case TextureSwapMode.Manual:
  161. mode.tooltip = "Textures are swapped by key press.";
  162. break;
  163. case TextureSwapMode.External:
  164. mode.tooltip = "Textures are swapped when SwapTexture() is called from script.";
  165. break;
  166. }
  167. ts.mode = ( TextureSwapMode )egui.EnumPopup( mode , ts.mode );
  168. gui.BeginVertical( GUI.skin.box );
  169. if ( ts.mode == TextureSwapMode.Automatic )
  170. ts.transitionDelay = egui.Slider( "Swap Delay" , ts.transitionDelay , 0.2f , 10f );
  171. else if ( ts.mode == TextureSwapMode.Manual )
  172. ts.swapKey = ( KeyCode )egui.EnumPopup( "Swap Key" , ts.swapKey );
  173. if ( ts.mode != TextureSwapMode.External )
  174. ts.randomOrder = egui.ToggleLeft( "Random Order" , ts.randomOrder );
  175. ts.transitionSpeed = egui.Slider( "Swap Speed" , ts.transitionSpeed , 0.5f , 10f );
  176. gui.EndVertical();
  177. egui.Space();
  178. SerializedObject o = new SerializedObject( target );
  179. egui.PropertyField( o.FindProperty( "textures" ) , new GUIContent( "Textures" ) , true );
  180. o.ApplyModifiedProperties();
  181. egui.Space();
  182. if ( Application.isPlaying )
  183. {
  184. gui.BeginHorizontal();
  185. if ( gui.Button( "Switch Texture" ) ) ts.SwapTexture();
  186. if ( gui.Button( " Toggle State " ) ) ts.ToggleState();
  187. gui.EndHorizontal();
  188. }
  189. }
  190. }
  191. #endif
  192. }