You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

294 lines
9.1 KiB

  1. // Amplify Shader Editor - Visual Shader Editing Tool
  2. // Copyright (c) Amplify Creations, Lda <info@amplify.pt>
  3. //
  4. // Donated by BinaryCats
  5. // https://forum.unity.com/threads/best-tool-asset-store-award-amplify-shader-editor-node-based-shader-creation-tool.430959/page-60#post-3414465
  6. //////////////////////
  7. // README / HOW TO USE
  8. //////////////////////
  9. // Examples:
  10. //
  11. // Floats:
  12. //
  13. // x Equals value
  14. // EditableIf( _float1, Equalto, 1)
  15. // This will allow the value to be edited, if the property _float1 is equal to 1. (_float1==1)
  16. // Note: NotEqualTo is also a valid argument which will do the opposite of this example.EditableIf(_float1, NotEqualTo, 1) (NotEqualTo != 1)
  17. //
  18. // x Greater than value
  19. // EditableIf(_Float1,GreaterThan,1)
  20. // This will allow the value to be edited if the property _float1 is Greater than 1. (_float1>1)
  21. //
  22. // x Greater Than Or Equal to value
  23. // EditableIf(_Float1,GreaterThanOrEqualTo,1)
  24. // This will allow the value to be edited if the property _float1 is Greater than or equal to 1. (_float1>=1)
  25. //
  26. //
  27. // x Less Than value
  28. // EditableIf(_Float1,LessThan,1)
  29. // This will allow the value to be edited if the property _float1 is Less than 1. (_float1<1)
  30. //
  31. // x Less Than Or Equal to value
  32. // EditableIf(_Float1,LessThanOrEqualTo,1)
  33. // This will allow the value to be edited if the property _float1 is Less than or equal to 1. (_float1<=1)
  34. //
  35. //
  36. // Colour:
  37. //
  38. // x Equals r,g,b,a
  39. // EditableIf(_Color0,EqualTo,255,255,255,255)
  40. // This will allow the value to be edited, if the property _Color0 R,G,B and A value all Equal 255. (_Color0.R==255 && _Color0.G==255 & _Color0.B == 255 && _Color0.A == 255)
  41. //
  42. // x Equals alpha
  43. // EditableIf(_Color0,EqualTo,null,null,null,255)
  44. // This will allow the value to be edited, if the property _Color0 Alpha value is Equal to 255. (_Color0.A == 255)
  45. //
  46. // a Greater than blue
  47. // EditableIf(_Color0,GreaterThan,null,null,125)
  48. // This will allow the value to be edited, if the property _Color0 Blue value is Greater Than 125. (_Color0.B > 125)
  49. // Note: as I do not want to check the Red or Green Values, i have entered "null" for the parameter
  50. // Note: I have not inputted a value to check for Alpha, as i do not want to check it. Simularly, if I wanted to Only check the Red Value I could have used EditableIf(_Color0,GreaterThan,125)
  51. //
  52. // Like wise with floats GreaterThanOrEqualTo, LessThan, LessThanOrEqualTo
  53. //
  54. // Vector:
  55. // Vector Checks work the same as colour checks
  56. //
  57. // Texture:
  58. // x Does Not have a Texture
  59. // EditableIf(_TextureSample0,Equals,null)
  60. // This will allow the value to be edited, if the property _TextureSample0 does NOT have a texture
  61. //
  62. // x Does have a Texture
  63. // EditableIf(_TextureSample0,NotEqualTo,null)
  64. // This will allow the value to be edited, if the property _TextureSample0 does have a texture
  65. using UnityEngine;
  66. using UnityEditor;
  67. using System;
  68. public enum ComparisonOperators
  69. {
  70. EqualTo, NotEqualTo, GreaterThan, LessThan, EqualsOrGreaterThan, EqualsOrLessThan, ContainsFlags,
  71. DoesNotContainsFlags
  72. }
  73. public class EditableIf : MaterialPropertyDrawer
  74. {
  75. ComparisonOperators op;
  76. string FieldName = "";
  77. object ExpectedValue;
  78. bool InputError;
  79. public EditableIf()
  80. {
  81. InputError = true;
  82. }
  83. public EditableIf( object fieldname, object comparison, object expectedvalue )
  84. {
  85. if( expectedvalue.ToString().ToLower() == "true" )
  86. {
  87. expectedvalue = (System.Single)1;
  88. }
  89. else if( expectedvalue.ToString().ToLower() == "false" )
  90. {
  91. expectedvalue = (System.Single)0;
  92. }
  93. Init( fieldname, comparison, expectedvalue );
  94. }
  95. public EditableIf( object fieldname, object comparison, object expectedvaluex, object expectedvaluey )
  96. {
  97. float? x = expectedvaluex as float?;
  98. float? y = expectedvaluey as float?;
  99. float? z = float.NegativeInfinity;
  100. float? w = float.NegativeInfinity;
  101. x = GetVectorValue( x );
  102. y = GetVectorValue( y );
  103. Init( fieldname, comparison, new Vector4( x.Value, y.Value, z.Value, w.Value ) );
  104. }
  105. public EditableIf( object fieldname, object comparison, object expectedvaluex, object expectedvaluey, object expectedvaluez )
  106. {
  107. float? x = expectedvaluex as float?;
  108. float? y = expectedvaluey as float?;
  109. float? z = expectedvaluez as float?;
  110. float? w = float.NegativeInfinity;
  111. x = GetVectorValue( x );
  112. y = GetVectorValue( y );
  113. z = GetVectorValue( z );
  114. Init( fieldname, comparison, new Vector4( x.Value, y.Value, z.Value, w.Value ) );
  115. }
  116. public EditableIf( object fieldname, object comparison, object expectedvaluex, object expectedvaluey, object expectedvaluez, object expectedvaluew )
  117. {
  118. var x = expectedvaluex as float?;
  119. var y = expectedvaluey as float?;
  120. var z = expectedvaluez as float?;
  121. var w = expectedvaluew as float?;
  122. x = GetVectorValue( x );
  123. y = GetVectorValue( y );
  124. z = GetVectorValue( z );
  125. w = GetVectorValue( w );
  126. Init( fieldname, comparison, new Vector4( x.Value, y.Value, z.Value, w.Value ) );
  127. }
  128. private void Init( object fieldname, object comparison, object expectedvalue )
  129. {
  130. FieldName = fieldname.ToString();
  131. var names = Enum.GetNames( typeof( ComparisonOperators ) );
  132. var name = comparison.ToString().ToLower().Replace( " ", "" );
  133. for( int i = 0; i < names.Length; i++ )
  134. {
  135. if( names[ i ].ToLower() == name )
  136. {
  137. op = (ComparisonOperators)i;
  138. break;
  139. }
  140. }
  141. ExpectedValue = expectedvalue;
  142. }
  143. private static float? GetVectorValue( float? x )
  144. {
  145. if( x.HasValue == false )
  146. {
  147. x = float.NegativeInfinity;
  148. }
  149. return x;
  150. }
  151. // Draw the property inside the given rect
  152. public override void OnGUI( Rect position, MaterialProperty prop, String label, MaterialEditor editor )
  153. {
  154. if( InputError )
  155. {
  156. EditorGUI.LabelField( position, "EditableIf Attribute Error: Input parameters are invalid!" );
  157. return;
  158. }
  159. var LHSprop = MaterialEditor.GetMaterialProperty( prop.targets, FieldName );
  160. if( string.IsNullOrEmpty( LHSprop.name ) )
  161. {
  162. LHSprop = MaterialEditor.GetMaterialProperty( prop.targets, "_" + FieldName.Replace( " ", "" ) );
  163. if( string.IsNullOrEmpty( LHSprop.name ) )
  164. {
  165. EditorGUI.LabelField( position, "EditableIf Attribute Error: " + FieldName + " Does not exist!" );
  166. return;
  167. }
  168. }
  169. object LHSVal = null;
  170. bool test = false;
  171. switch( LHSprop.type )
  172. {
  173. case MaterialProperty.PropType.Color:
  174. case MaterialProperty.PropType.Vector:
  175. LHSVal = LHSprop.type == MaterialProperty.PropType.Color ? (Vector4)LHSprop.colorValue : LHSprop.vectorValue;
  176. var v4 = ExpectedValue as Vector4?;
  177. v4 = v4.HasValue ? v4 : new Vector4( (System.Single)ExpectedValue, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity );
  178. if( LHSprop.type == MaterialProperty.PropType.Color )
  179. {
  180. test = VectorCheck( (Vector4)LHSVal, op, v4 / 255 );
  181. }
  182. else
  183. test = VectorCheck( (Vector4)LHSVal, op, v4 );
  184. break;
  185. case MaterialProperty.PropType.Range:
  186. case MaterialProperty.PropType.Float:
  187. LHSVal = LHSprop.floatValue;
  188. test = ( Check( LHSVal, op, ExpectedValue ) );
  189. break;
  190. case MaterialProperty.PropType.Texture:
  191. LHSVal = LHSprop.textureValue;
  192. test = ( CheckObject( LHSVal, op, ExpectedValue ) );
  193. break;
  194. }
  195. GUI.enabled = test;
  196. editor.DefaultShaderProperty( position, prop, label );
  197. GUI.enabled = true;
  198. }
  199. private bool VectorCheck( Vector4 LHS, ComparisonOperators op, object expectedValue )
  200. {
  201. var RHS = (Vector4)expectedValue;
  202. if( RHS.x != float.NegativeInfinity )
  203. {
  204. if( !Check( LHS.x, op, RHS.x ) )
  205. return false;
  206. }
  207. if( RHS.y != float.NegativeInfinity )
  208. {
  209. if( !Check( LHS.y, op, RHS.y ) )
  210. return false;
  211. }
  212. if( RHS.z != float.NegativeInfinity )
  213. {
  214. if( !Check( LHS.z, op, RHS.z ) )
  215. return false;
  216. }
  217. if( RHS.w != float.NegativeInfinity )
  218. {
  219. if( !Check( LHS.w, op, RHS.w ) )
  220. return false;
  221. }
  222. return true;
  223. }
  224. protected bool Check( object LHS, ComparisonOperators op, object RHS )
  225. {
  226. if( !( LHS is IComparable ) || !( RHS is IComparable ) )
  227. throw new Exception( "Check using non basic type" );
  228. switch( op )
  229. {
  230. case ComparisonOperators.EqualTo:
  231. return ( (IComparable)LHS ).CompareTo( RHS ) == 0;
  232. case ComparisonOperators.NotEqualTo:
  233. return ( (IComparable)LHS ).CompareTo( RHS ) != 0;
  234. case ComparisonOperators.EqualsOrGreaterThan:
  235. return ( (IComparable)LHS ).CompareTo( RHS ) >= 0;
  236. case ComparisonOperators.EqualsOrLessThan:
  237. return ( (IComparable)LHS ).CompareTo( RHS ) <= 0;
  238. case ComparisonOperators.GreaterThan:
  239. return ( (IComparable)LHS ).CompareTo( RHS ) > 0;
  240. case ComparisonOperators.LessThan:
  241. return ( (IComparable)LHS ).CompareTo( RHS ) < 0;
  242. case ComparisonOperators.ContainsFlags:
  243. return ( (int)LHS & (int)RHS ) != 0; // Dont trust LHS values, it has been casted to a char and then to an int again, first bit will be the sign
  244. case ComparisonOperators.DoesNotContainsFlags:
  245. return ( ( (int)LHS & (int)RHS ) == (int)LHS ); // Dont trust LHS values, it has been casted to a char and then to an int again, first bit will be the sign
  246. default:
  247. break;
  248. }
  249. return false;
  250. }
  251. private bool CheckObject( object LHS, ComparisonOperators comparasonOperator, object RHS )
  252. {
  253. switch( comparasonOperator )
  254. {
  255. case ComparisonOperators.EqualTo:
  256. return ( LHS == null );
  257. case ComparisonOperators.NotEqualTo:
  258. return ( LHS != null );
  259. }
  260. return true;
  261. }
  262. }