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.

199 lines
6.9 KiB

  1. using System;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. #if UNITY_EDITOR
  5. using UnityEditor;
  6. #endif
  7. namespace UnityStandardAssets.Utility
  8. {
  9. public class AutoMobileShaderSwitch : MonoBehaviour
  10. {
  11. [SerializeField] private ReplacementList m_ReplacementList;
  12. // Use this for initialization
  13. private void OnEnable()
  14. {
  15. #if UNITY_IPHONE || UNITY_ANDROID || UNITY_WP8 || UNITY_BLACKBERRY
  16. var renderers = FindObjectsOfType<Renderer>();
  17. Debug.Log (renderers.Length+" renderers");
  18. var oldMaterials = new List<Material>();
  19. var newMaterials = new List<Material>();
  20. int materialsReplaced = 0;
  21. int materialInstancesReplaced = 0;
  22. foreach(ReplacementDefinition replacementDef in m_ReplacementList.items)
  23. {
  24. foreach(var r in renderers)
  25. {
  26. Material[] modifiedMaterials = null;
  27. for(int n=0; n<r.sharedMaterials.Length; ++n)
  28. {
  29. var material = r.sharedMaterials[n];
  30. if (material.shader == replacementDef.original)
  31. {
  32. if (modifiedMaterials == null)
  33. {
  34. modifiedMaterials = r.materials;
  35. }
  36. if (!oldMaterials.Contains(material))
  37. {
  38. oldMaterials.Add(material);
  39. Material newMaterial = (Material)Instantiate(material);
  40. newMaterial.shader = replacementDef.replacement;
  41. newMaterials.Add(newMaterial);
  42. ++materialsReplaced;
  43. }
  44. Debug.Log ("replacing "+r.gameObject.name+" renderer "+n+" with "+newMaterials[oldMaterials.IndexOf(material)].name);
  45. modifiedMaterials[n] = newMaterials[oldMaterials.IndexOf(material)];
  46. ++materialInstancesReplaced;
  47. }
  48. }
  49. if (modifiedMaterials != null)
  50. {
  51. r.materials = modifiedMaterials;
  52. }
  53. }
  54. }
  55. Debug.Log (materialInstancesReplaced+" material instances replaced");
  56. Debug.Log (materialsReplaced+" materials replaced");
  57. for(int n=0; n<oldMaterials.Count; ++n)
  58. {
  59. Debug.Log (oldMaterials[n].name+" ("+oldMaterials[n].shader.name+")"+" replaced with "+newMaterials[n].name+" ("+newMaterials[n].shader.name+")");
  60. }
  61. #endif
  62. }
  63. [Serializable]
  64. public class ReplacementDefinition
  65. {
  66. public Shader original = null;
  67. public Shader replacement = null;
  68. }
  69. [Serializable]
  70. public class ReplacementList
  71. {
  72. public ReplacementDefinition[] items = new ReplacementDefinition[0];
  73. }
  74. }
  75. }
  76. namespace UnityStandardAssets.Utility.Inspector
  77. {
  78. #if UNITY_EDITOR
  79. [CustomPropertyDrawer(typeof (AutoMobileShaderSwitch.ReplacementList))]
  80. public class ReplacementListDrawer : PropertyDrawer
  81. {
  82. const float k_LineHeight = 18;
  83. const float k_Spacing = 4;
  84. public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
  85. {
  86. EditorGUI.BeginProperty(position, label, property);
  87. float x = position.x;
  88. float y = position.y;
  89. float inspectorWidth = position.width;
  90. // Don't make child fields be indented
  91. var indent = EditorGUI.indentLevel;
  92. EditorGUI.indentLevel = 0;
  93. var items = property.FindPropertyRelative("items");
  94. var titles = new string[] {"Original", "Replacement", ""};
  95. var props = new string[] {"original", "replacement", "-"};
  96. var widths = new float[] {.45f, .45f, .1f};
  97. const float lineHeight = 18;
  98. bool changedLength = false;
  99. if (items.arraySize > 0)
  100. {
  101. for (int i = -1; i < items.arraySize; ++i)
  102. {
  103. var item = items.GetArrayElementAtIndex(i);
  104. float rowX = x;
  105. for (int n = 0; n < props.Length; ++n)
  106. {
  107. float w = widths[n]*inspectorWidth;
  108. // Calculate rects
  109. Rect rect = new Rect(rowX, y, w, lineHeight);
  110. rowX += w;
  111. if (i == -1)
  112. {
  113. // draw title labels
  114. EditorGUI.LabelField(rect, titles[n]);
  115. }
  116. else
  117. {
  118. if (props[n] == "-" || props[n] == "^" || props[n] == "v")
  119. {
  120. if (GUI.Button(rect, props[n]))
  121. {
  122. switch (props[n])
  123. {
  124. case "-":
  125. items.DeleteArrayElementAtIndex(i);
  126. items.DeleteArrayElementAtIndex(i);
  127. changedLength = true;
  128. break;
  129. case "v":
  130. if (i > 0)
  131. {
  132. items.MoveArrayElement(i, i + 1);
  133. }
  134. break;
  135. case "^":
  136. if (i < items.arraySize - 1)
  137. {
  138. items.MoveArrayElement(i, i - 1);
  139. }
  140. break;
  141. }
  142. }
  143. }
  144. else
  145. {
  146. SerializedProperty prop = item.FindPropertyRelative(props[n]);
  147. EditorGUI.PropertyField(rect, prop, GUIContent.none);
  148. }
  149. }
  150. }
  151. y += lineHeight + k_Spacing;
  152. if (changedLength)
  153. {
  154. break;
  155. }
  156. }
  157. }
  158. // add button
  159. var addButtonRect = new Rect((x + position.width) - widths[widths.Length - 1]*inspectorWidth, y,
  160. widths[widths.Length - 1]*inspectorWidth, lineHeight);
  161. if (GUI.Button(addButtonRect, "+"))
  162. {
  163. items.InsertArrayElementAtIndex(items.arraySize);
  164. }
  165. y += lineHeight + k_Spacing;
  166. // Set indent back to what it was
  167. EditorGUI.indentLevel = indent;
  168. EditorGUI.EndProperty();
  169. }
  170. public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
  171. {
  172. SerializedProperty items = property.FindPropertyRelative("items");
  173. float lineAndSpace = k_LineHeight + k_Spacing;
  174. return 40 + (items.arraySize*lineAndSpace) + lineAndSpace;
  175. }
  176. }
  177. #endif
  178. }