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.

755 lines
27 KiB

  1. // Amplify Shader Editor - Visual Shader Editing Tool
  2. // Copyright (c) Amplify Creations, Lda <info@amplify.pt>
  3. using System;
  4. using System.Reflection;
  5. using System.Globalization;
  6. using UnityEngine;
  7. using AmplifyShaderEditor;
  8. namespace UnityEditor
  9. {
  10. [CustomEditor( typeof( Shader ) )]
  11. internal class CustomShaderInspector : Editor
  12. {
  13. internal class Styles
  14. {
  15. public static Texture2D errorIcon = EditorGUIUtilityEx.LoadIcon( "console.erroricon.sml" );
  16. public static Texture2D warningIcon = EditorGUIUtilityEx.LoadIcon( "console.warnicon.sml" );
  17. public static GUIContent showSurface = EditorGUIUtilityEx.TextContent( "Show generated code|Show generated code of a surface shader" );
  18. public static GUIContent showFF = EditorGUIUtilityEx.TextContent( "Show generated code|Show generated code of a fixed function shader" );
  19. public static GUIContent showCurrent = new GUIContent( "Compile and show code | ▾" );
  20. public static GUIStyle messageStyle = "CN StatusInfo";
  21. public static GUIStyle evenBackground = "CN EntryBackEven";
  22. public static GUIContent no = EditorGUIUtilityEx.TextContent( "no" );
  23. public static GUIContent builtinShader = EditorGUIUtilityEx.TextContent( "Built-in shader" );
  24. }
  25. private const float kSpace = 5f;
  26. private static readonly string[] kPropertyTypes = new string[]
  27. {
  28. "Color: ",
  29. "Vector: ",
  30. "Float: ",
  31. "Range: ",
  32. "Texture: "
  33. };
  34. private static readonly string[] kTextureTypes = new string[]
  35. {
  36. "No Texture?: ",
  37. "1D?: ",
  38. "2D: ",
  39. "3D: ",
  40. "Cube: ",
  41. "2DArray: ",
  42. "Any texture: "
  43. };
  44. private static readonly int kErrorViewHash = "ShaderErrorView".GetHashCode();
  45. private Vector2 m_ScrollPosition = Vector2.zero;
  46. private PreviewRenderUtility m_previewRenderUtility;
  47. private Material m_material;
  48. private Mesh m_previewMesh;
  49. private Vector2 m_mouseDelta;
  50. private Transform m_cameraTransform;
  51. private static int m_sliderHashCode = -1;
  52. private const float MaxDeltaY = 90;
  53. private const int DefaultMouseSpeed = 1;
  54. private const int ShiftMouseSpeed = 3;
  55. private const float DeltaMultiplier = 135f;
  56. private void ValidateData()
  57. {
  58. if ( m_previewRenderUtility == null )
  59. {
  60. m_previewRenderUtility = new PreviewRenderUtility();
  61. #if UNITY_2017_1_OR_NEWER
  62. m_cameraTransform = m_previewRenderUtility.camera.transform;
  63. #else
  64. m_cameraTransform = m_previewRenderUtility.m_Camera.transform;
  65. #endif
  66. m_cameraTransform.position = new Vector3( 0, 0, -4 );
  67. m_cameraTransform.rotation = Quaternion.identity;
  68. }
  69. if ( m_material == null )
  70. {
  71. m_material = new Material( target as Shader );
  72. m_material.hideFlags = HideFlags.DontSave;
  73. }
  74. if ( m_previewMesh == null )
  75. {
  76. m_previewMesh = Resources.GetBuiltinResource<Mesh>( "Sphere.fbx" );
  77. }
  78. if ( m_sliderHashCode < 0 )
  79. {
  80. "Slider".GetHashCode();
  81. }
  82. }
  83. public override bool HasPreviewGUI()
  84. {
  85. ValidateData();
  86. return true;
  87. }
  88. public static Vector2 CheckMouseMovement( Vector2 scrollPosition, Rect position )
  89. {
  90. int controlID = GUIUtility.GetControlID( m_sliderHashCode, FocusType.Passive );
  91. Event current = Event.current;
  92. switch ( current.GetTypeForControl( controlID ) )
  93. {
  94. case EventType.MouseDown:
  95. {
  96. if ( position.Contains( current.mousePosition ) && position.width > 50f )
  97. {
  98. GUIUtility.hotControl = controlID;
  99. current.Use();
  100. EditorGUIUtility.SetWantsMouseJumping( 1 );
  101. }
  102. }
  103. break;
  104. case EventType.MouseUp:
  105. {
  106. if ( GUIUtility.hotControl == controlID )
  107. {
  108. GUIUtility.hotControl = 0;
  109. }
  110. EditorGUIUtility.SetWantsMouseJumping( 0 );
  111. }
  112. break;
  113. case EventType.MouseDrag:
  114. {
  115. if ( GUIUtility.hotControl == controlID )
  116. {
  117. scrollPosition -= DeltaMultiplier * current.delta * ( float ) ( ( current.shift ) ? ShiftMouseSpeed : DefaultMouseSpeed ) / Mathf.Min( position.width, position.height );
  118. scrollPosition.y = Mathf.Clamp( scrollPosition.y, -MaxDeltaY, MaxDeltaY );
  119. current.Use();
  120. }
  121. }
  122. break;
  123. }
  124. return scrollPosition;
  125. }
  126. public override void OnPreviewGUI( Rect r, GUIStyle background )
  127. {
  128. m_mouseDelta = CheckMouseMovement( m_mouseDelta, r );
  129. if ( Event.current.type == EventType.Repaint )
  130. {
  131. m_previewRenderUtility.BeginPreview( r, background );
  132. Texture resultRender = m_previewRenderUtility.EndPreview();
  133. m_previewRenderUtility.DrawMesh( m_previewMesh, Matrix4x4.identity, m_material, 0 );
  134. m_cameraTransform.rotation = Quaternion.Euler( new Vector3( -m_mouseDelta.y, -m_mouseDelta.x, 0 ) );
  135. m_cameraTransform.position = m_cameraTransform.forward * -8f;
  136. #if UNITY_2017_1_OR_NEWER
  137. m_previewRenderUtility.camera.Render();
  138. #else
  139. m_previewRenderUtility.m_Camera.Render();
  140. #endif
  141. GUI.DrawTexture( r, resultRender, ScaleMode.StretchToFill, false );
  142. }
  143. }
  144. void OnDestroy()
  145. {
  146. CleanUp();
  147. }
  148. public void OnDisable()
  149. {
  150. CleanUp();
  151. }
  152. void CleanUp()
  153. {
  154. if( m_previewRenderUtility != null )
  155. {
  156. m_previewRenderUtility.Cleanup();
  157. m_previewRenderUtility = null;
  158. }
  159. if( m_previewMesh != null )
  160. {
  161. Resources.UnloadAsset( m_previewMesh );
  162. m_previewMesh = null;
  163. }
  164. if( m_previewRenderUtility != null )
  165. {
  166. m_previewRenderUtility.Cleanup();
  167. m_previewRenderUtility = null;
  168. }
  169. m_material = null;
  170. }
  171. public virtual void OnEnable()
  172. {
  173. Shader s = this.target as Shader;
  174. ShaderUtilEx.FetchCachedErrors( s );
  175. }
  176. private static string GetPropertyType( Shader s, int index )
  177. {
  178. UnityEditor.ShaderUtil.ShaderPropertyType propertyType = UnityEditor.ShaderUtil.GetPropertyType( s, index );
  179. if ( propertyType == UnityEditor.ShaderUtil.ShaderPropertyType.TexEnv )
  180. {
  181. return CustomShaderInspector.kTextureTypes[ ( int ) UnityEditor.ShaderUtil.GetTexDim( s, index ) ];
  182. }
  183. return CustomShaderInspector.kPropertyTypes[ ( int ) propertyType ];
  184. }
  185. public override void OnInspectorGUI()
  186. {
  187. Shader shader = this.target as Shader;
  188. if ( shader == null )
  189. {
  190. return;
  191. }
  192. GUI.enabled = true;
  193. GUILayout.Space( 3 );
  194. GUILayout.BeginHorizontal();
  195. {
  196. if ( GUILayout.Button( "Open in Shader Editor" ) )
  197. {
  198. AmplifyShaderEditorWindow.ConvertShaderToASE( shader );
  199. }
  200. if ( GUILayout.Button( "Open in Text Editor" ) )
  201. {
  202. if( UIUtils.IsUnityNativeShader( shader ) )
  203. {
  204. Debug.LogWarningFormat( "Action not allowed. Attempting to load the native {0} shader into Text Editor", shader.name );
  205. }
  206. else
  207. {
  208. AssetDatabase.OpenAsset( shader, 1 );
  209. }
  210. }
  211. }
  212. GUILayout.EndHorizontal();
  213. GUILayout.Space( 5 );
  214. EditorGUI.indentLevel = 0;
  215. this.ShowShaderCodeArea( shader );
  216. if ( shader.isSupported )
  217. {
  218. EditorGUILayout.LabelField( "Cast shadows", ( !ShaderUtilEx.HasShadowCasterPass( shader ) ) ? "no" : "yes", new GUILayoutOption[ 0 ] );
  219. EditorGUILayout.LabelField( "Render queue", ShaderUtilEx.GetRenderQueue( shader ).ToString( System.Globalization.CultureInfo.InvariantCulture ), new GUILayoutOption[ 0 ] );
  220. EditorGUILayout.LabelField( "LOD", ShaderUtilEx.GetLOD( shader ).ToString( System.Globalization.CultureInfo.InvariantCulture ), new GUILayoutOption[ 0 ] );
  221. EditorGUILayout.LabelField( "Ignore projector", ( !ShaderUtilEx.DoesIgnoreProjector( shader ) ) ? "no" : "yes", new GUILayoutOption[ 0 ] );
  222. string label;
  223. switch ( ShaderEx.GetDisableBatching( shader ) )
  224. {
  225. case DisableBatchingType.False:
  226. label = "no";
  227. break;
  228. case DisableBatchingType.True:
  229. label = "yes";
  230. break;
  231. case DisableBatchingType.WhenLODFading:
  232. label = "when LOD fading is on";
  233. break;
  234. default:
  235. label = "unknown";
  236. break;
  237. }
  238. EditorGUILayout.LabelField( "Disable batching", label, new GUILayoutOption[ 0 ] );
  239. CustomShaderInspector.ShowShaderProperties( shader );
  240. }
  241. }
  242. private void ShowShaderCodeArea( Shader s )
  243. {
  244. CustomShaderInspector.ShowSurfaceShaderButton( s );
  245. CustomShaderInspector.ShowFixedFunctionShaderButton( s );
  246. this.ShowCompiledCodeButton( s );
  247. this.ShowShaderErrors( s );
  248. }
  249. private static void ShowShaderProperties( Shader s )
  250. {
  251. GUILayout.Space( 5f );
  252. GUILayout.Label( "Properties:", EditorStyles.boldLabel, new GUILayoutOption[ 0 ] );
  253. int propertyCount = UnityEditor.ShaderUtil.GetPropertyCount( s );
  254. for ( int i = 0; i < propertyCount; i++ )
  255. {
  256. string propertyName = UnityEditor.ShaderUtil.GetPropertyName( s, i );
  257. string label = CustomShaderInspector.GetPropertyType( s, i ) + UnityEditor.ShaderUtil.GetPropertyDescription( s, i );
  258. EditorGUILayout.LabelField( propertyName, label, new GUILayoutOption[ 0 ] );
  259. }
  260. }
  261. internal static void ShaderErrorListUI( UnityEngine.Object shader, ShaderError[] errors, ref Vector2 scrollPosition )
  262. {
  263. int num = errors.Length;
  264. GUILayout.Space( 5f );
  265. GUILayout.Label( string.Format( "Errors ({0}):", num ), EditorStyles.boldLabel, new GUILayoutOption[ 0 ] );
  266. int controlID = GUIUtility.GetControlID( CustomShaderInspector.kErrorViewHash, FocusType.Passive );
  267. float minHeight = Mathf.Min( ( float ) num * 20f + 40f, 150f );
  268. scrollPosition = GUILayout.BeginScrollView( scrollPosition, GUISkinEx.GetCurrentSkin().box, new GUILayoutOption[]
  269. {
  270. GUILayout.MinHeight(minHeight)
  271. } );
  272. EditorGUIUtility.SetIconSize( new Vector2( 16f, 16f ) );
  273. float height = CustomShaderInspector.Styles.messageStyle.CalcHeight( EditorGUIUtilityEx.TempContent( CustomShaderInspector.Styles.errorIcon ), 100f );
  274. Event current = Event.current;
  275. for ( int i = 0; i < num; i++ )
  276. {
  277. Rect controlRect = EditorGUILayout.GetControlRect( false, height, new GUILayoutOption[ 0 ] );
  278. string message = errors[ i ].message;
  279. string platform = errors[ i ].platform;
  280. bool flag = errors[ i ].warning != 0;
  281. string lastPathNameComponent = FileUtilEx.GetLastPathNameComponent( errors[ i ].file );
  282. int line = errors[ i ].line;
  283. if ( current.type == EventType.MouseDown && current.button == 0 && controlRect.Contains( current.mousePosition ) )
  284. {
  285. GUIUtility.keyboardControl = controlID;
  286. if ( current.clickCount == 2 )
  287. {
  288. string file = errors[ i ].file;
  289. UnityEngine.Object @object = ( !string.IsNullOrEmpty( file ) ) ? AssetDatabase.LoadMainAssetAtPath( file ) : null;
  290. AssetDatabase.OpenAsset( @object ?? shader, line );
  291. GUIUtility.ExitGUI();
  292. }
  293. current.Use();
  294. }
  295. if ( current.type == EventType.ContextClick && controlRect.Contains( current.mousePosition ) )
  296. {
  297. current.Use();
  298. GenericMenu genericMenu = new GenericMenu();
  299. int errorIndex = i;
  300. genericMenu.AddItem( new GUIContent( "Copy error text" ), false, delegate
  301. {
  302. string text = errors[ errorIndex ].message;
  303. if ( !string.IsNullOrEmpty( errors[ errorIndex ].messageDetails ) )
  304. {
  305. text += '\n';
  306. text += errors[ errorIndex ].messageDetails;
  307. }
  308. EditorGUIUtility.systemCopyBuffer = text;
  309. } );
  310. genericMenu.ShowAsContext();
  311. }
  312. if ( current.type == EventType.Repaint && ( i & 1 ) == 0 )
  313. {
  314. GUIStyle evenBackground = CustomShaderInspector.Styles.evenBackground;
  315. evenBackground.Draw( controlRect, false, false, false, false );
  316. }
  317. Rect rect = controlRect;
  318. rect.xMin = rect.xMax;
  319. if ( line > 0 )
  320. {
  321. GUIContent content;
  322. if ( string.IsNullOrEmpty( lastPathNameComponent ) )
  323. {
  324. content = EditorGUIUtilityEx.TempContent( line.ToString( System.Globalization.CultureInfo.InvariantCulture ) );
  325. }
  326. else
  327. {
  328. content = EditorGUIUtilityEx.TempContent( lastPathNameComponent + ":" + line.ToString( System.Globalization.CultureInfo.InvariantCulture ) );
  329. }
  330. Vector2 vector = EditorStyles.miniLabel.CalcSize( content );
  331. rect.xMin -= vector.x;
  332. GUI.Label( rect, content, EditorStyles.miniLabel );
  333. rect.xMin -= 2f;
  334. if ( rect.width < 30f )
  335. {
  336. rect.xMin = rect.xMax - 30f;
  337. }
  338. }
  339. Rect position = rect;
  340. position.width = 0f;
  341. if ( platform.Length > 0 )
  342. {
  343. GUIContent content2 = EditorGUIUtilityEx.TempContent( platform );
  344. Vector2 vector2 = EditorStyles.miniLabel.CalcSize( content2 );
  345. position.xMin -= vector2.x;
  346. Color contentColor = GUI.contentColor;
  347. GUI.contentColor = new Color( 1f, 1f, 1f, 0.5f );
  348. GUI.Label( position, content2, EditorStyles.miniLabel );
  349. GUI.contentColor = contentColor;
  350. position.xMin -= 2f;
  351. }
  352. Rect position2 = controlRect;
  353. position2.xMax = position.xMin;
  354. GUI.Label( position2, EditorGUIUtilityEx.TempContent( message, ( !flag ) ? CustomShaderInspector.Styles.errorIcon : CustomShaderInspector.Styles.warningIcon ), CustomShaderInspector.Styles.messageStyle );
  355. }
  356. EditorGUIUtility.SetIconSize( Vector2.zero );
  357. GUILayout.EndScrollView();
  358. }
  359. private void ShowShaderErrors( Shader s )
  360. {
  361. int shaderErrorCount = ShaderUtilEx.GetShaderErrorCount( s );
  362. if ( shaderErrorCount < 1 )
  363. {
  364. return;
  365. }
  366. CustomShaderInspector.ShaderErrorListUI( s, ShaderUtilEx.GetShaderErrors( s ), ref this.m_ScrollPosition );
  367. }
  368. private void ShowCompiledCodeButton( Shader s )
  369. {
  370. EditorGUILayout.BeginHorizontal( new GUILayoutOption[ 0 ] );
  371. EditorGUILayout.PrefixLabel( "Compiled code", EditorStyles.miniButton );
  372. bool flag = ShaderUtilEx.HasShaderSnippets( s ) || ShaderUtilEx.HasSurfaceShaders( s ) || ShaderUtilEx.HasFixedFunctionShaders( s );
  373. if ( flag )
  374. {
  375. GUIContent showCurrent = CustomShaderInspector.Styles.showCurrent;
  376. Rect rect = GUILayoutUtility.GetRect( showCurrent, EditorStyles.miniButton, new GUILayoutOption[]
  377. {
  378. GUILayout.ExpandWidth(false)
  379. } );
  380. Rect position = new Rect( rect.xMax - 16f, rect.y, 16f, rect.height );
  381. if ( EditorGUIEx.ButtonMouseDown( position, GUIContent.none, FocusType.Passive, GUIStyle.none ) )
  382. {
  383. Rect last = GUILayoutUtilityEx.TopLevel_GetLast();
  384. PopupWindow.Show( last, ( PopupWindowContent ) Activator.CreateInstance( System.Type.GetType( "UnityEditor.ShaderInspectorPlatformsPopup, UnityEditor" ), new object[] { s } ) );
  385. GUIUtility.ExitGUI();
  386. }
  387. if ( GUI.Button( rect, showCurrent, EditorStyles.miniButton ) )
  388. {
  389. ShaderUtilEx.OpenCompiledShader( s, ShaderInspectorPlatformsPopupEx.GetCurrentMode(), ShaderInspectorPlatformsPopupEx.GetCurrentPlatformMask(), ShaderInspectorPlatformsPopupEx.GetCurrentVariantStripping() == 0 );
  390. GUIUtility.ExitGUI();
  391. }
  392. }
  393. else
  394. {
  395. GUILayout.Button( "none (precompiled shader)", GUI.skin.label, new GUILayoutOption[ 0 ] );
  396. }
  397. EditorGUILayout.EndHorizontal();
  398. }
  399. private static void ShowSurfaceShaderButton( Shader s )
  400. {
  401. bool flag = ShaderUtilEx.HasSurfaceShaders( s );
  402. EditorGUILayout.BeginHorizontal( new GUILayoutOption[ 0 ] );
  403. EditorGUILayout.PrefixLabel( "Surface shader", EditorStyles.miniButton );
  404. if ( flag )
  405. {
  406. if ( !( AssetImporter.GetAtPath( AssetDatabase.GetAssetPath( s ) ) == null ) )
  407. {
  408. if ( GUILayout.Button( CustomShaderInspector.Styles.showSurface, EditorStyles.miniButton, new GUILayoutOption[]
  409. {
  410. GUILayout.ExpandWidth(false)
  411. } ) )
  412. {
  413. ShaderUtilEx.OpenParsedSurfaceShader( s );
  414. GUIUtility.ExitGUI();
  415. }
  416. }
  417. else
  418. {
  419. GUILayout.Button( CustomShaderInspector.Styles.builtinShader, GUI.skin.label, new GUILayoutOption[ 0 ] );
  420. }
  421. }
  422. else
  423. {
  424. GUILayout.Button( CustomShaderInspector.Styles.no, GUI.skin.label, new GUILayoutOption[ 0 ] );
  425. }
  426. EditorGUILayout.EndHorizontal();
  427. }
  428. private static void ShowFixedFunctionShaderButton( Shader s )
  429. {
  430. bool flag = ShaderUtilEx.HasFixedFunctionShaders( s );
  431. EditorGUILayout.BeginHorizontal( new GUILayoutOption[ 0 ] );
  432. EditorGUILayout.PrefixLabel( "Fixed function", EditorStyles.miniButton );
  433. if ( flag )
  434. {
  435. if ( !( AssetImporter.GetAtPath( AssetDatabase.GetAssetPath( s ) ) == null ) )
  436. {
  437. if ( GUILayout.Button( CustomShaderInspector.Styles.showFF, EditorStyles.miniButton, new GUILayoutOption[]
  438. {
  439. GUILayout.ExpandWidth(false)
  440. } ) )
  441. {
  442. ShaderUtilEx.OpenGeneratedFixedFunctionShader( s );
  443. GUIUtility.ExitGUI();
  444. }
  445. }
  446. else
  447. {
  448. GUILayout.Button( CustomShaderInspector.Styles.builtinShader, GUI.skin.label, new GUILayoutOption[ 0 ] );
  449. }
  450. }
  451. else
  452. {
  453. GUILayout.Button( CustomShaderInspector.Styles.no, GUI.skin.label, new GUILayoutOption[ 0 ] );
  454. }
  455. EditorGUILayout.EndHorizontal();
  456. }
  457. }
  458. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  459. // UNITY EDITOR EXTENSIONS
  460. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  461. public enum DisableBatchingType
  462. {
  463. False,
  464. True,
  465. WhenLODFading
  466. }
  467. public struct ShaderError
  468. {
  469. public string message;
  470. public string messageDetails;
  471. public string platform;
  472. public string file;
  473. public int line;
  474. public int warning;
  475. }
  476. public static class EditorGUIUtilityEx
  477. {
  478. private static System.Type type = null;
  479. public static System.Type Type { get { return ( type == null ) ? type = System.Type.GetType( "UnityEditor.EditorGUIUtility, UnityEditor" ) : type; } }
  480. public static Texture2D LoadIcon( string icon )
  481. {
  482. return ( Texture2D ) EditorGUIUtilityEx.Type.InvokeMember( "LoadIcon", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { icon } );
  483. }
  484. public static GUIContent TextContent( string t )
  485. {
  486. return ( GUIContent ) EditorGUIUtilityEx.Type.InvokeMember( "TextContent", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { t } );
  487. }
  488. internal static GUIContent TempContent( string t )
  489. {
  490. return ( GUIContent ) EditorGUIUtilityEx.Type.InvokeMember( "TempContent", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { t } );
  491. }
  492. internal static GUIContent TempContent( Texture i )
  493. {
  494. return ( GUIContent ) EditorGUIUtilityEx.Type.InvokeMember( "TempContent", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { i } );
  495. }
  496. internal static GUIContent TempContent( string t, Texture i )
  497. {
  498. return ( GUIContent ) EditorGUIUtilityEx.Type.InvokeMember( "TempContent", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { t, i } );
  499. }
  500. }
  501. public static class GUILayoutUtilityEx
  502. {
  503. private static System.Type type = null;
  504. public static System.Type Type { get { return ( type == null ) ? type = System.Type.GetType( "UnityEngine.GUILayoutUtility, UnityEngine" ) : type; } }
  505. public static Rect TopLevel_GetLast()
  506. {
  507. System.Type guiLayoutGroup = System.Type.GetType( "UnityEngine.GUILayoutGroup, UnityEngine" );
  508. var topLevel = GUILayoutUtilityEx.Type.GetProperty( "topLevel", BindingFlags.NonPublic | BindingFlags.Static ).GetValue( null, null );
  509. return ( Rect ) guiLayoutGroup.InvokeMember( "GetLast", BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod, null, topLevel, new object[] { } );
  510. }
  511. }
  512. public static class ShaderEx
  513. {
  514. private static System.Type type = null;
  515. public static System.Type Type { get { return ( type == null ) ? type = System.Type.GetType( "UnityEngine.Shader, UnityEngine" ) : type; } }
  516. public static DisableBatchingType GetDisableBatching( Shader s )
  517. {
  518. return ( DisableBatchingType ) ShaderEx.Type.GetProperty( "disableBatching", BindingFlags.NonPublic | BindingFlags.Instance ).GetValue( s, new object[ 0 ] );
  519. }
  520. }
  521. public static class ShaderUtilEx
  522. {
  523. private static System.Type type = null;
  524. public static System.Type Type { get { return ( type == null ) ? type = System.Type.GetType( "UnityEditor.ShaderUtil, UnityEditor" ) : type; } }
  525. public static void OpenParsedSurfaceShader( Shader s )
  526. {
  527. ShaderUtilEx.Type.InvokeMember( "OpenParsedSurfaceShader", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { s } );
  528. }
  529. public static void OpenGeneratedFixedFunctionShader( Shader s )
  530. {
  531. ShaderUtilEx.Type.InvokeMember( "OpenGeneratedFixedFunctionShader", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { s } );
  532. }
  533. public static void OpenCompiledShader( Shader shader, int mode, int customPlatformsMask, bool includeAllVariants )
  534. {
  535. ShaderUtilEx.Type.InvokeMember( "OpenCompiledShader", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { shader, mode, customPlatformsMask, includeAllVariants } );
  536. }
  537. public static void FetchCachedErrors( Shader s )
  538. {
  539. ShaderUtilEx.Type.InvokeMember( "FetchCachedErrors", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { s } );
  540. }
  541. public static int GetShaderErrorCount( Shader s )
  542. {
  543. return ( int ) ShaderUtilEx.Type.InvokeMember( "GetShaderErrorCount", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { s } );
  544. }
  545. public static int GetAvailableShaderCompilerPlatforms()
  546. {
  547. return (int)ShaderUtilEx.Type.InvokeMember( "GetAvailableShaderCompilerPlatforms", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { } );
  548. }
  549. public static ShaderError[] GetShaderErrors( Shader s )
  550. {
  551. System.Type shaderErrorType = System.Type.GetType( "UnityEditor.ShaderError, UnityEditor" );
  552. var errorList = ( System.Collections.IList ) ShaderUtilEx.Type.InvokeMember( "GetShaderErrors", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { s } );
  553. FieldInfo messageField = shaderErrorType.GetField( "message", BindingFlags.Public | BindingFlags.Instance );
  554. FieldInfo messageDetailsField = shaderErrorType.GetField( "messageDetails", BindingFlags.Public | BindingFlags.Instance );
  555. FieldInfo platformField = shaderErrorType.GetField( "platform", BindingFlags.Public | BindingFlags.Instance );
  556. FieldInfo fileField = shaderErrorType.GetField( "file", BindingFlags.Public | BindingFlags.Instance );
  557. FieldInfo lineField = shaderErrorType.GetField( "line", BindingFlags.Public | BindingFlags.Instance );
  558. FieldInfo warningField = shaderErrorType.GetField( "warning", BindingFlags.Public | BindingFlags.Instance );
  559. ShaderError[] errors = new ShaderError[ errorList.Count ];
  560. for ( int i = 0; i < errorList.Count; i++ )
  561. {
  562. errors[ i ].message = ( string ) messageField.GetValue( errorList[ i ] );
  563. errors[ i ].messageDetails = ( string ) messageDetailsField.GetValue( errorList[ i ] );
  564. errors[ i ].platform = ( string ) platformField.GetValue( errorList[ i ] );
  565. errors[ i ].file = ( string ) fileField.GetValue( errorList[ i ] );
  566. errors[ i ].line = ( int ) lineField.GetValue( errorList[ i ] );
  567. errors[ i ].warning = ( int ) warningField.GetValue( errorList[ i ] );
  568. }
  569. return errors;
  570. }
  571. public static bool HasShaderSnippets( Shader s )
  572. {
  573. return ( bool ) ShaderUtilEx.Type.InvokeMember( "HasShaderSnippets", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { s } );
  574. }
  575. public static bool HasSurfaceShaders( Shader s )
  576. {
  577. return ( bool ) ShaderUtilEx.Type.InvokeMember( "HasSurfaceShaders", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { s } );
  578. }
  579. public static bool HasFixedFunctionShaders( Shader s )
  580. {
  581. return ( bool ) ShaderUtilEx.Type.InvokeMember( "HasFixedFunctionShaders", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { s } );
  582. }
  583. public static bool HasShadowCasterPass( Shader s )
  584. {
  585. return ( bool ) ShaderUtilEx.Type.InvokeMember( "HasShadowCasterPass", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { s } );
  586. }
  587. public static int GetRenderQueue( Shader s )
  588. {
  589. return ( int ) ShaderUtilEx.Type.InvokeMember( "GetRenderQueue", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { s } );
  590. }
  591. public static int GetLOD( Shader s )
  592. {
  593. return ( int ) ShaderUtilEx.Type.InvokeMember( "GetLOD", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { s } );
  594. }
  595. public static bool DoesIgnoreProjector( Shader s )
  596. {
  597. return ( bool ) ShaderUtilEx.Type.InvokeMember( "DoesIgnoreProjector", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { s } );
  598. }
  599. }
  600. public static class FileUtilEx
  601. {
  602. private static System.Type type = null;
  603. public static System.Type Type { get { return ( type == null ) ? type = System.Type.GetType( "UnityEditor.FileUtil, UnityEditor" ) : type; } }
  604. public static string GetLastPathNameComponent( string path )
  605. {
  606. return ( string ) FileUtilEx.Type.InvokeMember( "GetLastPathNameComponent", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { path } );
  607. }
  608. }
  609. public static class ShaderInspectorEx
  610. {
  611. private static System.Type type = null;
  612. public static System.Type Type { get { return ( type == null ) ? type = System.Type.GetType( "UnityEditor.ShaderInspector, UnityEditor" ) : type; } }
  613. }
  614. public static class GUISkinEx
  615. {
  616. private static System.Type type = null;
  617. public static System.Type Type { get { return ( type == null ) ? type = System.Type.GetType( "UnityEngine.GUISkin, UnityEngine" ) : type; } }
  618. public static GUISkin GetCurrentSkin()
  619. {
  620. return ( GUISkin ) GUISkinEx.Type.GetField( "current", BindingFlags.NonPublic | BindingFlags.Static ).GetValue( null );
  621. }
  622. }
  623. public static class EditorGUIEx
  624. {
  625. private static System.Type type = null;
  626. public static System.Type Type { get { return ( type == null ) ? type = System.Type.GetType( "UnityEditor.EditorGUI, UnityEditor" ) : type; } }
  627. public static bool ButtonMouseDown( Rect position, GUIContent content, FocusType focusType, GUIStyle style )
  628. {
  629. #if UNITY_5_6_OR_NEWER
  630. return EditorGUI.DropdownButton( position, content, focusType, style );
  631. #else
  632. return ( bool ) EditorGUIEx.Type.InvokeMember( "ButtonMouseDown", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, new object[] { position, content, focusType, style } );
  633. #endif
  634. }
  635. public static float kObjectFieldMiniThumbnailHeight
  636. {
  637. get
  638. {
  639. return (float)EditorGUIEx.Type.InvokeMember( "kObjectFieldMiniThumbnailHeight", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.GetField, null, null, new object[] {} );
  640. }
  641. }
  642. public static float kSingleLineHeight
  643. {
  644. get
  645. {
  646. return (float)EditorGUIEx.Type.InvokeMember( "kSingleLineHeight", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.GetField, null, null, new object[] { } );
  647. }
  648. }
  649. }
  650. public static class ShaderInspectorPlatformsPopupEx
  651. {
  652. private static System.Type type = null;
  653. public static System.Type Type { get { return ( type == null ) ? type = System.Type.GetType( "UnityEditor.ShaderInspectorPlatformsPopup, UnityEditor" ) : type; } }
  654. public static int GetCurrentMode()
  655. {
  656. return ( int ) ShaderInspectorPlatformsPopupEx.Type.GetProperty( "currentMode", BindingFlags.Public | BindingFlags.Static ).GetValue( null, null );
  657. }
  658. public static int GetCurrentPlatformMask()
  659. {
  660. return ( int ) ShaderInspectorPlatformsPopupEx.Type.GetProperty( "currentPlatformMask", BindingFlags.Public | BindingFlags.Static ).GetValue( null, null );
  661. }
  662. public static int GetCurrentVariantStripping()
  663. {
  664. return ( int ) ShaderInspectorPlatformsPopupEx.Type.GetProperty( "currentVariantStripping", BindingFlags.Public | BindingFlags.Static ).GetValue( null, null );
  665. }
  666. }
  667. }