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