public static glTF_VRM_Material CreateFromMaterial(Material m, List <Texture> textures) { var material = new glTF_VRM_Material { name = m.name, shader = m.shader.name, renderQueue = m.renderQueue, }; #if UNITY_EDITOR for (int i = 0; i < ShaderUtil.GetPropertyCount(m.shader); ++i) { var name = ShaderUtil.GetPropertyName(m.shader, i); var propType = ShaderUtil.GetPropertyType(m.shader, i); switch (propType) { case ShaderUtil.ShaderPropertyType.Color: { var value = m.GetColor(name).ToArray(); material.vectorProperties.Add(name, value); } break; case ShaderUtil.ShaderPropertyType.Range: case ShaderUtil.ShaderPropertyType.Float: { var value = m.GetFloat(name); material.floatProperties.Add(name, value); } break; case ShaderUtil.ShaderPropertyType.TexEnv: { var texture = m.GetTexture(name); if (texture != null) { var value = textures.IndexOf(texture); if (value == -1) { Debug.LogFormat("not found {0}", texture.name); } else { material.textureProperties.Add(name, value); } } // offset & scaling var offset = m.GetTextureOffset(name); var scaling = m.GetTextureScale(name); material.vectorProperties.Add(name, new float[] { offset.x, offset.y, scaling.x, scaling.y }); } break; case ShaderUtil.ShaderPropertyType.Vector: { var value = m.GetVector(name).ToArray(); material.vectorProperties.Add(name, value); } break; default: throw new NotImplementedException(); } } #else Debug.LogWarning("cannot export material properties on runtime"); #endif foreach (var keyword in m.shaderKeywords) { material.keywordMap.Add(keyword, m.IsKeywordEnabled(keyword)); } foreach (var tag in TAGS) { var value = m.GetTag(tag, false); if (!String.IsNullOrEmpty(value)) { material.tagMap.Add(tag, value); } } return(material); }
public override void OnInspectorGUI() { EditorGUI.BeginChangeCheck(); SerializedProperty gradients = serializedObject.FindProperty("gradients"); SerializedProperty renderTextures = serializedObject.FindProperty("renderTextures"); SerializedProperty wrapMode = serializedObject.FindProperty("wrapMode"); SerializedProperty filterMode = serializedObject.FindProperty("filterMode"); SerializedProperty resolution = serializedObject.FindProperty("resolution"); SerializedProperty useSharedMaterial = serializedObject.FindProperty("useSharedMaterial"); SerializedProperty anisoLevel = serializedObject.FindProperty("anisoLevel"); GradientTexture ct = target as GradientTexture; Renderer r = ct.GetComponent <Renderer>(); if (r == null) { EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("global name"); ct.globalName = EditorGUILayout.TextField(ct.globalName); EditorGUILayout.EndHorizontal(); } else { Material mat = r.sharedMaterial; Shader s = mat.shader; int count = ShaderUtil.GetPropertyCount(s); List <string> textureNames = new List <string>(); for (int i = 0; i < count; ++i) { if (ShaderUtil.GetPropertyType(s, i) == ShaderUtil.ShaderPropertyType.TexEnv) { textureNames.Add(ShaderUtil.GetPropertyName(s, i)); } } int index = textureNames.IndexOf(ct.propertyName); int newIdx = EditorGUILayout.Popup(index, textureNames.ToArray()); if (newIdx != index) { ct.propertyName = textureNames[newIdx]; } } EditorGUILayout.PropertyField(gradients); EditorGUILayout.PropertyField(renderTextures); EditorGUILayout.PropertyField(wrapMode); EditorGUILayout.PropertyField(filterMode); EditorGUILayout.PropertyField(resolution); if (r != null) { EditorGUILayout.PropertyField(useSharedMaterial); } EditorGUILayout.PropertyField(anisoLevel); if (EditorGUI.EndChangeCheck()) { serializedObject.ApplyModifiedProperties(); ct.Refresh(); } if (GUILayout.Button("Save Texture")) { //Texture2D tex = ct.Generate(false); ct.RenderTexutures(false); /* * string path = EditorUtility.SaveFilePanel("Save Texture", Application.dataPath, "curve", "png"); * if (!string.IsNullOrEmpty(path)) * { * Texture2D tex = ct.Generate(false); * byte[] bytes = tex.EncodeToPNG(); * File.WriteAllBytes(path, bytes); * DestroyImmediate(tex); * AssetImporter ai = AssetImporter.GetAtPath(path); * if (ai != null) * { * TextureImporter ti = ai as TextureImporter; * ti.anisoLevel = ct.anisoLevel; * ti.linearTexture = true; * ti.generateMipsInLinearSpace = true; * ti.filterMode = ct.filterMode; * ti.wrapMode = ct.wrapMode; * ti.textureFormat = TextureImporterFormat.ARGB32; * ti.SaveAndReimport(); * } * } */ } }
public override VFXExpressionMapper GetExpressionMapper(VFXDeviceTarget target) { var meshData = (VFXDataMesh)GetData(); switch (target) { case VFXDeviceTarget.GPU: { var mapper = new VFXExpressionMapper(); for (int i = 2; i < GetNbInputSlots(); ++i) { VFXExpression exp = GetInputSlot(i).GetExpression(); VFXProperty prop = GetInputSlot(i).property; // As there's not shader generation here, we need expressions that can be evaluated on CPU if (exp.IsAny(VFXExpression.Flags.NotCompilableOnCPU)) { throw new InvalidOperationException(string.Format("Expression for slot {0} must be evaluable on CPU: {1}", prop.name, exp)); } // needs to convert to srgb as color are linear in vfx graph // This should not be performed for colors with the attribute [HDR] and be performed for vector4 with the attribute [Gamma] // But property attributes cannot seem to be accessible from C# :( if (prop.type == typeof(Color)) { exp = VFXOperatorUtility.LinearToGamma(exp); } mapper.AddExpression(exp, prop.name, -1); } return(mapper); } case VFXDeviceTarget.CPU: { var mapper = new VFXExpressionMapper(); mapper.AddExpression(GetInputSlot(0).GetExpression(), "mesh", -1); mapper.AddExpression(GetInputSlot(1).GetExpression(), "transform", -1); mapper.AddExpression(GetInputSlot(2).GetExpression(), "subMeshMask", -1); // TODO Remove this once material are serialized // Add material properties if (shader != null) { var mat = meshData.GetOrCreateMaterial(); for (int i = 0; i < ShaderUtil.GetPropertyCount(shader); ++i) { if (ShaderUtil.IsShaderPropertyHidden(shader, i)) { var name = ShaderUtil.GetPropertyName(shader, i); var nameId = Shader.PropertyToID(name); if (!mat.HasProperty(nameId)) { continue; } VFXExpression expr = null; switch (ShaderUtil.GetPropertyType(shader, i)) { case ShaderUtil.ShaderPropertyType.Float: expr = VFXValue.Constant <float>(mat.GetFloat(nameId)); break; default: break; } if (expr != null) { mapper.AddExpression(expr, name, -1); } } } } return(mapper); } default: return(null); } }
/// <summary> /// 分析显示相关数据 /// </summary> private void ParseRendererInfo(GameObject go) { // 获取所有的粒子系统组件 _cloneObject.GetComponentsInChildren <ParticleSystem>(true, _allParticles); // 获取所有唯一的材质球 _allMaterials.Clear(); Renderer[] rendererList = go.GetComponentsInChildren <Renderer>(true); foreach (var rd in rendererList) { if (rd.enabled == false) { ParticleSystem ps = rd.gameObject.GetComponent <ParticleSystem>(); if (ps.emission.enabled) { _errors.Add($"{rd.gameObject.name} 粒子系统组件:Renderer未启用,请关闭Emission发射器!"); } } foreach (var mat in rd.sharedMaterials) { if (mat == null) { if (rd.enabled) { _errors.Add($"{rd.gameObject.name} 粒子系统组件:Renderer已启用,但是缺少材质球!"); } continue; } if (_allMaterials.Contains(mat) == false) { _allMaterials.Add(mat); } } } // 获取所有唯一的纹理 _allTextures.Clear(); foreach (var mat in _allMaterials) { int count = ShaderUtil.GetPropertyCount(mat.shader); for (int i = 0; i < count; i++) { ShaderUtil.ShaderPropertyType propertyType = ShaderUtil.GetPropertyType(mat.shader, i); if (propertyType == ShaderUtil.ShaderPropertyType.TexEnv) { string propertyName = ShaderUtil.GetPropertyName(mat.shader, i); Texture tex = mat.GetTexture(propertyName); if (tex != null) { if (_allTextures.Contains(tex) == false) { _allTextures.Add(tex); } } } } } foreach (var ps in _allParticles) { ParticleSystem.TextureSheetAnimationModule tm = ps.textureSheetAnimation; if (tm.mode == ParticleSystemAnimationMode.Sprites) { for (int i = 0; i < tm.spriteCount; i++) { Sprite sprite = tm.GetSprite(i); if (sprite != null && sprite.texture != null) { if (_allTextures.Contains(sprite.texture) == false) { _allTextures.Add(sprite.texture); } } } } } // 获取所有唯一的网格 _allMeshs.Clear(); MeshFilter[] list1 = go.GetComponentsInChildren <MeshFilter>(); foreach (var meshFilter in list1) { if (meshFilter.sharedMesh != null) { if (_allMeshs.Contains(meshFilter.sharedMesh) == false) { _allMeshs.Add(meshFilter.sharedMesh); } } } SkinnedMeshRenderer[] list2 = go.GetComponentsInChildren <SkinnedMeshRenderer>(); foreach (var skinMesh in list2) { if (skinMesh.sharedMesh != null) { if (_allMeshs.Contains(skinMesh.sharedMesh) == false) { _allMeshs.Add(skinMesh.sharedMesh); } } } foreach (var ps in _allParticles) { var psr = ps.GetComponent <ParticleSystemRenderer>(); if (psr != null && psr.renderMode == ParticleSystemRenderMode.Mesh) { if (psr.mesh != null) { if (_allMeshs.Contains(psr.mesh) == false) { _allMeshs.Add(psr.mesh); } } } } // 计算材质数量 MaterialCount = _allMaterials.Count; // 计算纹理数量和所需内存大小 TextureCount = _allTextures.Count; TextureMemory = 0; foreach (var tex in _allTextures) { TextureMemory += GetStorageMemorySize(tex); } // 计算特效生命周期 CurveSampleTime = 1f; foreach (var ps in _allParticles) { float playingTime = ps.main.duration; float delayTime = GetMaxTime(ps.main.startDelay); float lifeTime = GetMaxTime(ps.main.startLifetime); if ((delayTime + lifeTime) > playingTime) { playingTime = delayTime + lifeTime; } if (playingTime > CurveSampleTime) { CurveSampleTime = playingTime; } } }
public static void DrawAnimatableProperties(SerializedProperty sp, Material mat) { if (!mat || !mat.shader) { return; } bool isClicked = false; using (new EditorGUILayout.HorizontalScope(GUILayout.ExpandWidth(false))) { var r = EditorGUI.PrefixLabel(EditorGUILayout.GetControlRect(true), new GUIContent(sp.displayName, sp.tooltip)); isClicked = GUI.Button(r, CollectActiveNames(sp, s_ActiveNames), EditorStyles.popup); } if (isClicked) { GenericMenu gm = new GenericMenu(); gm.AddItem(new GUIContent("Nothing"), s_ActiveNames.Count == 0, () => { sp.ClearArray(); sp.serializedObject.ApplyModifiedProperties(); }); for (int i = 0; i < sp.arraySize; i++) { var p = sp.GetArrayElementAtIndex(i); var name = p.FindPropertyRelative("m_Name").stringValue; var type = (ShaderPropertyType)p.FindPropertyRelative("m_Type").intValue; AddMenu(gm, sp, new AnimatedPropertiesEditor() { name = name, type = type }, false); } for (int i = 0; i < ShaderUtil.GetPropertyCount(mat.shader); i++) { var pName = ShaderUtil.GetPropertyName(mat.shader, i); var type = (ShaderPropertyType)ShaderUtil.GetPropertyType(mat.shader, i); AddMenu(gm, sp, new AnimatedPropertiesEditor() { name = pName, type = type }, true); if (type == ShaderPropertyType.Texture) { AddMenu(gm, sp, new AnimatedPropertiesEditor() { name = pName + "_ST", type = ShaderPropertyType.Vector }, true); AddMenu(gm, sp, new AnimatedPropertiesEditor() { name = pName + "_HDR", type = ShaderPropertyType.Vector }, true); AddMenu(gm, sp, new AnimatedPropertiesEditor() { name = pName + "_TexelSize", type = ShaderPropertyType.Vector }, true); } } gm.ShowAsContext(); } }
private static List <string> GetShaderPropertyList(Shader shader, ShaderUtil.ShaderPropertyType[] filterTypes = null) { List <string> results = new List <string>(); if (shader == null) { return(results); } int count = ShaderUtil.GetPropertyCount(shader); results.Capacity = count; for (int i = 0; i < count; i++) { bool isHidden = ShaderUtil.IsShaderPropertyHidden(shader, i); bool isValidPropertyType = filterTypes == null || filterTypes.Contains(ShaderUtil.GetPropertyType(shader, i)); if (!isHidden && isValidPropertyType) { results.Add(ShaderUtil.GetPropertyName(shader, i)); } } results.Sort(); return(results); }
private void ShaderPropertyImpl(Shader shader, int propertyIndex) { Material myMat = target as Material; Material[] mats = new Material[1] { myMat }; MaterialProperty aProp = MaterialEditor.GetMaterialProperty(mats, propertyIndex); GUIStyle boldFoldoutStyle = new GUIStyle(EditorStyles.foldout); boldFoldoutStyle.fontStyle = FontStyle.Bold; Color c; int i = propertyIndex; bool separator_flag = false; string label = ShaderUtil.GetPropertyDescription(shader, i); if (label.IndexOf("<") >= 0) { label = label.Substring(1); separator_flag = true; } string propertyName = ShaderUtil.GetPropertyName(shader, i); bool adjustementFlag = false; if (ShaderUtil.GetPropertyType(shader, i) == ShaderUtil.ShaderPropertyType.Float) { if (propertyName == "BlockStart") { adjustementFlag = true; EditorGUILayout.BeginVertical("box"); c = GUI.color; GUI.color = new Color(0.8f, 1, 0.8f); GUILayout.BeginHorizontal(); GUILayout.Space(12); propBlockAvailable = IsAvailable(ref label); if (propBlockAvailable) { bool newVal = EditorGUILayout.Foldout(VolumeGrassMaterialInspector.blocks[i], label, boldFoldoutStyle); if (VolumeGrassMaterialInspector.blocks[i] != newVal) { VolumeGrassMaterialInspector.blocks[i] = newVal; EditorUtility.SetDirty(target); } } else { EditorGUILayout.LabelField(label + " (switched off)"); } unfolded = VolumeGrassMaterialInspector.blocks[i]; GUILayout.EndHorizontal(); GUI.color = c; GUILayout.BeginHorizontal(); GUILayout.Space(10); GUILayout.BeginVertical(); } else if (propertyName == "BlockEnd") { adjustementFlag = true; unfolded = true; propBlockAvailable = true; GUILayout.EndVertical(); GUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); GUILayout.Space(3); } } if (!unfolded || !propBlockAvailable) { return; } if (separator_flag) { GUILayout.Space(8); } switch (ShaderUtil.GetPropertyType(shader, i)) { case ShaderUtil.ShaderPropertyType.Range: // float ranges { GUILayout.BeginHorizontal(); RangeProperty(aProp, label); GUILayout.EndHorizontal(); break; } case ShaderUtil.ShaderPropertyType.Float: // floats { if (!adjustementFlag) { FloatProperty(aProp, label); } break; } case ShaderUtil.ShaderPropertyType.Color: // colors { ColorProperty(aProp, label); break; } case ShaderUtil.ShaderPropertyType.TexEnv: // textures { TextureProperty(aProp, label, false); GUILayout.Space(6); break; } case ShaderUtil.ShaderPropertyType.Vector: // vectors { VectorProperty(aProp, label); break; } default: { GUILayout.Label("(unknown prop type for " + label + " ): " + ShaderUtil.GetPropertyType(shader, i)); break; } } }
/// <summary> /// Write the material file for an OBJ. This function handles making the list of Materials unique & ensuring unique names for each group. Material to named mtl group are stored in materialMap. /// </summary> /// <param name="models"></param> /// <param name="options"></param> /// <param name="materialMap"></param> /// <param name="textures"></param> /// <returns></returns> static string WriteMtlContents(IEnumerable <Model> models, ObjOptions options, out Dictionary <Material, string> materialMap, out List <string> textures) { materialMap = new Dictionary <Material, string>(); foreach (Model model in models) { for (int i = 0, c = model.submeshCount; i < c; i++) { Material material = model.materials[i]; if (material == null) { continue; } if (!materialMap.ContainsKey(material)) { string escapedName = material.name.Replace(" ", "_"); string name = escapedName; int nameIncrement = 1; while (materialMap.Any(x => x.Value.Equals(name))) { name = string.Format("{0}_{1}", escapedName, nameIncrement++); } materialMap.Add(material, name); } } } StringBuilder sb = new StringBuilder(); textures = new List <string>(); foreach (KeyValuePair <Material, string> group in materialMap) { Material mat = group.Key; sb.AppendLine(string.Format("newmtl {0}", group.Value)); // Texture maps if (mat.shader != null) { for (int i = 0; i < ShaderUtil.GetPropertyCount(mat.shader); i++) { if (ShaderUtil.GetPropertyType(mat.shader, i) != ShaderUtil.ShaderPropertyType.TexEnv) { continue; } string texPropertyName = ShaderUtil.GetPropertyName(mat.shader, i); Texture texture = mat.GetTexture(texPropertyName); string path = texture != null?AssetDatabase.GetAssetPath(texture) : null; if (!string.IsNullOrEmpty(path)) { if (options.copyTextures) { textures.Add(path); } // remove "Assets/" from start of path path = path.Substring(7, path.Length - 7); string textureName = options.copyTextures ? Path.GetFileName(path) : string.Format("{0}/{1}", Application.dataPath, path); string mtlKey = null; if (s_TextureMapKeys.TryGetValue(texPropertyName, out mtlKey)) { Vector2 offset = mat.GetTextureOffset(texPropertyName); Vector2 scale = mat.GetTextureScale(texPropertyName); if (options.textureOffsetScale) { sb.AppendLine(string.Format(CultureInfo.InvariantCulture, "{0} -o {1} {2} -s {3} {4} {5}", mtlKey, offset.x, offset.y, scale.x, scale.y, textureName)); } else { sb.AppendLine(string.Format("{0} {1}", mtlKey, textureName)); } } } } } Color color = mat.color; if (mat.HasProperty("_BaseColorMap") || mat.HasProperty("_BaseMap")) // HDRP || URP { color = mat.GetColor("_BaseColor"); // Diffuse sb.AppendLine(string.Format("Kd {0}", string.Format(CultureInfo.InvariantCulture, "{0} {1} {2}", color.r, color.g, color.b))); // Transparency sb.AppendLine(string.Format(CultureInfo.InvariantCulture, "d {0}", color.a)); } else if (mat.HasProperty("_Color")) { // Diffuse sb.AppendLine(string.Format("Kd {0}", string.Format(CultureInfo.InvariantCulture, "{0} {1} {2}", color.r, color.g, color.b))); // Transparency sb.AppendLine(string.Format(CultureInfo.InvariantCulture, "d {0}", color.a)); } else { sb.AppendLine("Kd 1.0 1.0 1.0"); sb.AppendLine("d 1.0"); } sb.AppendLine(); } return(sb.ToString()); }
void OnGUI() { if (shaders == null) { this.shaders = ShaderHelper.GetThryEditorShaderNames(); if (Mediator.active_shader != null) { for (int i = 0; i < shaders.Length; i++) { if (shaders[i] == Mediator.active_shader.name) { selectedShaderIndex = i; } } } } if (propertyBackground == null) { setupStyle(); } Shader activeShader = Mediator.active_shader; int newIndex = EditorGUILayout.Popup(selectedShaderIndex, shaders, GUILayout.MaxWidth(500)); if (selectedShaderIndex == -1) { newIndex = 0; } if (newIndex != selectedShaderIndex) { selectedShaderIndex = newIndex; selectedPreset = 0; Mediator.SetActiveShader(Shader.Find(shaders[selectedShaderIndex])); activeShader = Mediator.active_shader; reloadProperties = true; } if (activeShader != null) { PresetHandler presetHandler = Mediator.active_shader_preset_handler; if (presetHandler.shaderHasPresetPath()) { Dictionary <string, List <string[]> > presets = presetHandler.getPresets(); string[] presetStrings = new string[presets.Count + 1]; int i = 0; foreach (KeyValuePair <string, List <string[]> > entry in presets) { presetStrings[i++] = entry.Key; } presetStrings[presets.Count] = Locale.editor.Get("new_preset2"); GUILayout.BeginHorizontal(); int newSelectedPreset = EditorGUILayout.Popup(selectedPreset, presetStrings, GUILayout.MaxWidth(500)); if (newSelectedPreset != selectedPreset || reloadProperties) { this.selectedPreset = newSelectedPreset; if (newSelectedPreset == presetStrings.Length - 1) { newPreset = true; newPresetName = Locale.editor.Get("new_preset_name2"); properties = null; } else { this.properties = presetHandler.getPropertiesOfPreset(presetStrings[selectedPreset]); List <string> unusedProperties = new List <string>(); foreach (string pName in presetHandler.getPropertyNames()) { bool unused = true; foreach (string[] p in this.properties) { if (p[0] == pName) { unused = false; } } if (unused) { unusedProperties.Add(pName); } } this.unusedProperties = unusedProperties.ToArray(); reloadProperties = false; newPreset = false; } } if (GUILayout.Button(Locale.editor.Get("delete"), GUILayout.MaxWidth(80))) { presetHandler.removePreset(presetStrings[selectedPreset]); reloadProperties = true; Repaint(); } GUILayout.EndHorizontal(); if (newPreset) { GUILayout.BeginHorizontal(); newPresetName = GUILayout.TextField(newPresetName, GUILayout.MaxWidth(150)); if (GUILayout.Button(Locale.editor.Get("add_preset"), GUILayout.MaxWidth(80))) { presetHandler.addNewPreset(newPresetName); reloadProperties = true; Repaint(); selectedPreset = presetStrings.Length - 1; } GUILayout.EndHorizontal(); } scrollPos = GUILayout.BeginScrollView(scrollPos); if (properties != null) { for (i = 0; i < properties.Count; i++) { if (i % 2 == 0) { GUILayout.BeginHorizontal(propertyBackground); } else { GUILayout.BeginHorizontal(); } //properties[i][0] = GUILayout.TextField(properties[i][0], GUILayout.MaxWidth(200)); GUILayout.Label(properties[i][0], GUILayout.MaxWidth(150)); bool typeFound = false; ShaderUtil.ShaderPropertyType propertyType = ShaderUtil.ShaderPropertyType.Float; for (int p = 0; p < ShaderUtil.GetPropertyCount(activeShader); p++) { if (ShaderUtil.GetPropertyName(activeShader, p) == properties[i][0]) { propertyType = ShaderUtil.GetPropertyType(activeShader, p); typeFound = true; break; } } if (typeFound) { switch (propertyType) { case ShaderUtil.ShaderPropertyType.Color: float[] rgba = new float[4] { 1, 1, 1, 1 }; string[] rgbaString = properties[i][1].Split(','); if (rgbaString.Length > 0) { float.TryParse(rgbaString[0], out rgba[0]); } if (rgbaString.Length > 1) { float.TryParse(rgbaString[1], out rgba[1]); } if (rgbaString.Length > 2) { float.TryParse(rgbaString[2], out rgba[2]); } if (rgbaString.Length > 3) { float.TryParse(rgbaString[3], out rgba[3]); } Color p = EditorGUI.ColorField(EditorGUILayout.GetControlRect(GUILayout.MaxWidth(204)), new GUIContent(), new Color(rgba[0], rgba[1], rgba[2], rgba[3]), true, true, true, new ColorPickerHDRConfig(0, 1000, 0, 1000)); properties[i][1] = "" + p.r + "," + p.g + "," + p.b + "," + p.a; break; case ShaderUtil.ShaderPropertyType.TexEnv: Texture texture = AssetDatabase.LoadAssetAtPath <Texture>(properties[i][1]); #pragma warning disable CS0618 // Type or member is obsolete texture = (Texture)EditorGUI.ObjectField(EditorGUILayout.GetControlRect(GUILayout.MaxWidth(100)), texture, typeof(Texture)); #pragma warning restore CS0618 // Type or member is obsolete GUILayout.Label("(" + properties[i][1] + ")", GUILayout.MaxWidth(100)); break; case ShaderUtil.ShaderPropertyType.Vector: Vector4 vector = Converter.stringToVector(properties[i][1]); vector = EditorGUI.Vector4Field(EditorGUILayout.GetControlRect(GUILayout.MaxWidth(204)), "", vector); properties[i][1] = "" + vector.x + "," + vector.y + "," + vector.z + "," + vector.w; break; default: properties[i][1] = GUILayout.TextField(properties[i][1], GUILayout.MaxWidth(204)); break; } } else { properties[i][1] = GUILayout.TextField(properties[i][1], GUILayout.MaxWidth(204)); } if (GUILayout.Button(Locale.editor.Get("delete"), GUILayout.MaxWidth(80))) { properties.RemoveAt(i); this.reloadProperties = true; saveProperties(presetHandler, presetStrings); } GUILayout.EndHorizontal(); } //new preset gui GUILayout.BeginHorizontal(); addPropertyIndex = EditorGUILayout.Popup(addPropertyIndex, unusedProperties, GUILayout.MaxWidth(150)); if (GUILayout.Button(Locale.editor.Get("add"), GUILayout.MaxWidth(80))) { this.reloadProperties = true; properties.Add(new string[] { unusedProperties[addPropertyIndex], "" }); saveProperties(presetHandler, presetStrings); } GUILayout.EndHorizontal(); } GUILayout.EndScrollView(); if (GUILayout.Button(Locale.editor.Get("save"), GUILayout.MinWidth(50))) { saveProperties(presetHandler, presetStrings); } Event e = Event.current; if (e.isKey) { if (Event.current.keyCode == (KeyCode.Return)) { saveProperties(presetHandler, presetStrings); } } } } }
void OnGUI() { EditorGUI.BeginChangeCheck(); EditorGUILayout.Toggle("开启资源预览检查特效", openPreview); if (EditorGUI.EndChangeCheck()) { psCount = 0; meshTrian = 0; meshPSCount = 0; openPreview = !openPreview; if (!openPreview) { if (dqEffect != null && shiLieHua > 0) { DestroyImmediate(dqEffect); zaiRu = false; } else { dqEffect = null; zaiRu = false; } ListClear(); } dqPrefab = null; OnSelectionChange(); } EditorGUILayout.LabelField("当前特效的最大粒子数: " + psCount); EditorGUILayout.LabelField("当前特效大概的三角面数: " + ((meshTrian / 3) + (psCount * 2)).ToString()); EditorGUILayout.LabelField("当前特效发射mesh的ParticleSystem数: " + meshPSCount); EditorGUILayout.Space(); EditorGUILayout.ObjectField("上次选择的预设: ", scSPrefab, typeof(GameObject), false); EditorGUILayout.LabelField("当前特效的材质数量: " + matCounts.Count); EditorGUILayout.LabelField("当前特效的贴图数量: " + texCounts.Count); scrollPos = EditorGUILayout.BeginScrollView(scrollPos); if (objCounts.Count > 0) { foreach (var obj in objCounts) { GUILayout.BeginHorizontal(); GUILayout.BeginVertical(GUILayout.Width(200)); EditorGUILayout.ObjectField(obj, typeof(GameObject), false, GUILayout.Width(200)); if (obj) { var ps = obj.GetComponent <ParticleSystem>(); if (ps) { if (ps.GetComponent <ParticleSystemRenderer>().renderMode == ParticleSystemRenderMode.Mesh && ps.GetComponent <ParticleSystemRenderer>().mesh != null) { EditorGUILayout.LabelField("PS.Mesh的面数: " + (ps.GetComponent <ParticleSystemRenderer>().mesh.triangles.Length / 3)); } } var meshF = obj.GetComponent <MeshFilter>(); if (meshF) { if (meshF.sharedMesh) { EditorGUILayout.LabelField("Mesh的面数: " + (meshF.sharedMesh.triangles.Length / 3)); } } var meshSkinF = obj.GetComponent <SkinnedMeshRenderer>(); if (meshSkinF) { if (meshSkinF.sharedMesh) { EditorGUILayout.LabelField("Mesh的面数: " + (meshSkinF.sharedMesh.triangles.Length / 3)); } } } GUILayout.EndVertical(); if (obj != null) { var rend = obj.GetComponent <Renderer>(); var matS = rend.sharedMaterials; if (matS.Length > 0) { foreach (var mat in matS) { if (mat != null) { var matLB = (Material)EditorGUILayout.ObjectField(mat, typeof(Material), false, GUILayout.Width(200)); int count = ShaderUtil.GetPropertyCount(mat.shader); for (int i = 0; i < count; i++) { var matShaderType = ShaderUtil.GetPropertyType(mat.shader, i); if (ShaderUtil.ShaderPropertyType.TexEnv == matShaderType) { var assetMatShaderProName = ShaderUtil.GetPropertyName(mat.shader, i); var tex = mat.GetTexture(assetMatShaderProName); if (tex != null) { tex = (Texture)EditorGUILayout.ObjectField("像素: " + tex.height + "*" + tex.width, tex, typeof(Texture), false, GUILayout.Width(200)); } } } } } } } GUILayout.EndHorizontal(); EditorGUILayout.Space(); } } EditorGUILayout.EndScrollView(); }
public static void convert(MenuCommand command) { var graphicRenderer = (command.context as MeshRenderer).GetComponentInParent <LeapGraphicRenderer>(); if (graphicRenderer.groups.Count == 0) { graphicRenderer.editor.CreateGroup(typeof(LeapBakedRenderer)); } var group = graphicRenderer.groups[0]; var graphics = new List <LeapMeshGraphic>(); var meshRenderers = (command.context as MeshRenderer).GetComponentsInChildren <MeshRenderer>(); foreach (var meshRenderer in meshRenderers) { var material = meshRenderer.sharedMaterial; if (material == null) { continue; } var shader = material.shader; if (shader == null) { continue; } var filter = meshRenderer.GetComponent <MeshFilter>(); if (filter == null) { continue; } var mesh = filter.sharedMesh; if (mesh == null) { continue; } int propCount = ShaderUtil.GetPropertyCount(shader); for (int i = 0; i < propCount; i++) { if (ShaderUtil.GetPropertyType(shader, i) == ShaderUtil.ShaderPropertyType.TexEnv) { string propName = ShaderUtil.GetPropertyName(shader, i); if (material.GetTexture(propName) == null) { continue; } var feature = group.features.Query(). OfType <LeapTextureFeature>(). FirstOrDefault(f => f.propertyName == propName); if (feature == null) { feature = group.editor.AddFeature(typeof(LeapTextureFeature)) as LeapTextureFeature; feature.channel = UnityEngine.Rendering.UVChannelFlags.UV0; feature.propertyName = propName; } } } var graphic = meshRenderer.gameObject.AddComponent <LeapMeshGraphic>(); Undo.RegisterCreatedObjectUndo(graphic, "Create Leap Mesh Graphic"); group.TryAddGraphic(graphic); graphics.Add(graphic); } foreach (var graphic in graphics) { var meshRenderer = graphic.GetComponent <MeshRenderer>(); var meshFilter = graphic.GetComponent <MeshFilter>(); var material = meshRenderer.sharedMaterial; graphic.SetMesh(meshFilter.sharedMesh); foreach (var dataObj in graphic.featureData) { var textureData = dataObj as LeapTextureData; if (textureData == null) { continue; } var feature = textureData.feature as LeapTextureFeature; if (!material.HasProperty(feature.propertyName)) { continue; } Texture2D tex2d = material.GetTexture(feature.propertyName) as Texture2D; if (tex2d == null) { continue; } textureData.texture = tex2d; } Undo.DestroyObjectImmediate(meshRenderer); Undo.DestroyObjectImmediate(meshFilter); } group.renderer.editor.ScheduleRebuild(); }
void YouHuaJianCha(GameObject go) { ListClear(); var objTranS = go.GetComponentsInChildren <Transform>(); if (objTranS.Length > 0) { foreach (var objTran in objTranS) { var obj = objTran.gameObject; var rend = obj.GetComponent <Renderer>(); if (rend != null) { if (!objCounts.Contains(obj)) { objCounts.Add(obj); } } } } var meshs = go.GetComponentsInChildren <MeshFilter>(); foreach (var mesh in meshs) { if (mesh.sharedMesh != null) { meshTrians.Add(mesh.sharedMesh.triangles.Length); } } var psS = go.GetComponentsInChildren <ParticleSystem>(); foreach (var ps in psS) { var psConut = ps.GetParticles(new ParticleSystem.Particle[ps.maxParticles]); if (ps.GetComponent <ParticleSystemRenderer>().renderMode == ParticleSystemRenderMode.Mesh && ps.GetComponent <ParticleSystemRenderer>().mesh != null) { meshTrians.Add(ps.GetComponent <ParticleSystemRenderer>().mesh.triangles.Length *psConut); meshPSCount = meshPSCount + 1; } var psNum = ps.GetParticles(new ParticleSystem.Particle[ps.maxParticles]); psCounts.Add(psNum); } var skinMeshs = go.GetComponentsInChildren <SkinnedMeshRenderer>(); foreach (var mesh in skinMeshs) { if (mesh.sharedMesh != null) { meshTrians.Add(mesh.sharedMesh.triangles.Length); } } var rendS = go.GetComponentsInChildren <Renderer>(); if (rendS.Length > 0) { foreach (var rend in rendS) { var matS = rend.sharedMaterials; if (matS.Length > 0) { foreach (var mat in matS) { if (mat != null) { if (!matCounts.Contains(mat)) { matCounts.Add(mat); } } else { Debug.LogError("这个预设有缺少材质!!!!!!!"); } } } } } if (matCounts.Count > 0) { foreach (var mat in matCounts) { int count = ShaderUtil.GetPropertyCount(mat.shader); for (int i = 0; i < count; i++) { var matShaderType = ShaderUtil.GetPropertyType(mat.shader, i); if (ShaderUtil.ShaderPropertyType.TexEnv == matShaderType) { var assetMatShaderProName = ShaderUtil.GetPropertyName(mat.shader, i); var tex = mat.GetTexture(assetMatShaderProName); if (tex != null) { //查找list里是否存在某个对象 if (!texCounts.Contains(tex)) { texCounts.Add(tex); } } } } } } if (meshTrians.Count > 0) { var psNum = 0; foreach (var item in meshTrians) { psNum = psNum + item; } if (meshTrian < psNum) { meshTrian = psNum; } } if (psCounts.Count > 0) { var psNum = 0; foreach (var item in psCounts) { psNum = psNum + item; } if (psCount < psNum) { psCount = psNum; } } Repaint(); }
void OnGUI_ShaderProps() { MaterialAnimHelper helper = target as MaterialAnimHelper; if (helper == null) { return; } var mat = helper.mat; if (mat == null) { return; } var shader = mat.shader; if (shader == null) { return; } var propCount = ShaderUtil.GetPropertyCount(shader); if (propCount < 1) { return; } Dictionary <string, ShaderPropInfo> props = new Dictionary <string, ShaderPropInfo>(); List <string> propNames = new List <string>(); propNames.Add("None"); for (int i = 0; i < propCount; i++) { var propType = ShaderUtil.GetPropertyType(shader, i); if (propType == ShaderUtil.ShaderPropertyType.TexEnv) { continue; } var propName = ShaderUtil.GetPropertyName(shader, i); propNames.Add(propName); props.Add(propName, new ShaderPropInfo() { index = i, type = propType } ); } if (props.Count < 1) { return; } //prop1 OnGUI_HelperPropInfo(shader, ref helper.propName1, ref helper.param1, ref helper.propType1, propNames, props, "Prop1"); //prop2 OnGUI_HelperPropInfo(shader, ref helper.propName2, ref helper.param2, ref helper.propType2, propNames, props, "Prop2"); //prop3 OnGUI_HelperPropInfo(shader, ref helper.propName3, ref helper.param3, ref helper.propType3, propNames, props, "Prop3"); //prop4 OnGUI_HelperPropInfo(shader, ref helper.propName4, ref helper.param4, ref helper.propType4, propNames, props, "Prop4"); //prop5 OnGUI_HelperPropInfo(shader, ref helper.propName5, ref helper.param5, ref helper.propType5, propNames, props, "Prop5"); helper.InitShaderProp(); }
private static string MaterialPropertyName(string property, Material mat, PropertyTypeEnum type, bool allowNone, string defaultProperty, string labelName) { Color tColor = GUI.color; // Create a list of available color and value properties List <string> props = new List <string>(); int selectedPropIndex = 0; if (allowNone) { props.Add("(None)"); } if (mat != null) { int propertyCount = ShaderUtil.GetPropertyCount(mat.shader); string propName = string.Empty; for (int i = 0; i < propertyCount; i++) { if (ShaderUtil.GetPropertyType(mat.shader, i).ToString() == type.ToString()) { propName = ShaderUtil.GetPropertyName(mat.shader, i); if (propName == property) { // We've found our current property selectedPropIndex = props.Count; } props.Add(propName); } } if (string.IsNullOrEmpty(labelName)) { labelName = type.ToString(); } int newPropIndex = EditorGUILayout.Popup(labelName, selectedPropIndex, props.ToArray()); if (allowNone) { property = (newPropIndex > 0 ? props[newPropIndex] : string.Empty); } else { if (props.Count > 0) { property = props[newPropIndex]; } else { property = defaultProperty; } } return(property); } else { GUI.color = Color.Lerp(tColor, Color.gray, 0.5f); // Draw an empty property EditorGUILayout.Popup(labelName, selectedPropIndex, props.ToArray()); GUI.color = tColor; return(string.Empty); } }
public List <GenericPreset.Property> Explore(GenericPreset template) { Shader shader = material.shader; if (Application.isEditor && template == null) { #if UNITY_EDITOR int numProperties = ShaderUtil.GetPropertyCount(shader); if (properties == null) { properties = new List <GenericPreset.Property> (numProperties); } else { properties.Clear(); } for (int i = 0; i < numProperties; i++) { string propertyName = ShaderUtil.GetPropertyName(shader, i); ShaderUtil.ShaderPropertyType type = ShaderUtil.GetPropertyType(shader, i); GenericPreset.Property property = new GenericPreset.Property(propertyName, GenericPreset.PType.Null); switch (type) { case ShaderUtil.ShaderPropertyType.Float: case ShaderUtil.ShaderPropertyType.Range: property = new GenericPreset.Property(propertyName, material.GetFloat(propertyName)); break; case ShaderUtil.ShaderPropertyType.Vector: property = new GenericPreset.Property(propertyName, ( Vector3 )material.GetVector(propertyName)); break; case ShaderUtil.ShaderPropertyType.Color: property = new GenericPreset.Property(propertyName, material.GetColor(propertyName)); break; } properties.Add(property); } return(properties); #endif } if (properties == null && template == null) { return(null); } if (properties == null || properties.Count != template.properties.Count) { FromPreset(template); } foreach (GenericPreset.Property property in properties) { string propertyName = property.key; switch (property.type) { case GenericPreset.PType.Number: property.Value = material.GetFloat(propertyName); break; case GenericPreset.PType.V3: property.Value = material.GetVector(propertyName); break; case GenericPreset.PType.Color: property.Value = material.GetColor(propertyName); break; } } return(properties); }
static void BuildOneAssetBundle(string expcur, Dictionary <string, int> objmark, Dictionary <string, List <string> > allobjchild, string path, ref int depcount) { // 假设已经输出则跳过 if (objmark.ContainsKey(expcur)) { return; } List <string> subs = allobjchild[expcur]; if (subs != null) { foreach (string sub in subs) { // 假设已经输出则跳过 if (objmark.ContainsKey(sub)) { continue; } BuildOneAssetBundle(sub, objmark, allobjchild, path, ref depcount); } } objmark[expcur] = 1; string asspath = expcur; if (string.IsNullOrEmpty(asspath)) { return; } string guid = AssetDatabase.AssetPathToGUID(asspath); string assetpath = ConvertFileName(Path.GetDirectoryName(asspath)); string outpath; if (asspath != "") { outpath = path + "/" + assetpath; } else { outpath = assetpath; } Directory.CreateDirectory(outpath); //string outfile = Path.Combine(outpath, Path.GetFileNameWithoutExtension(asspath)); string outfile = outpath + "/" + guid; BuildPipeline.PushAssetDependencies(); depcount++; Object realass = AssetDatabase.LoadMainAssetAtPath(expcur); if (realass == null) { return; } Object[] depobjs = EditorUtility.CollectDependencies(new Object[] { realass }); Dictionary <string, int> deppathmap = new Dictionary <string, int>(); foreach (Object depobj in depobjs) { string deppath = AssetDatabase.GetAssetPath(depobj); if (string.IsNullOrEmpty(deppath)) { continue; } deppathmap[deppath] = 1; } List <string> realsubs = new List <string>(); if (subs != null) { foreach (string sub in subs) { if (deppathmap.ContainsKey(sub)) { string realname = ConvertFileName(sub) + ".u3dext"; realsubs.Add(realname.ToLower()); } } } BuildAssetBundleOptions option; option = BuildAssetBundleOptions.DeterministicAssetBundle | BuildAssetBundleOptions.CompleteAssets | BuildAssetBundleOptions.CollectDependencies; option |= BuildAssetBundleOptions.UncompressedAssetBundle; bool suc = BuildPipeline.BuildAssetBundleExplicitAssetNames(new Object[] { realass }, new string[] { "1" }, outfile, option, ExportAssetBundlesHelper.CurBuildTarget); Debug.Log("src file: " + asspath + " " + depcount); if (/*realass is MonoScript || */ !deppathmap.ContainsKey(expcur)) { File.Delete(outfile); } else if (suc) { // do not compress font bool ForceSep = realass is Font; bool NeedSep = false; if (!ForceSep) { FileInfo fi = new FileInfo(outfile); if (realass is AudioClip) { if (fi.Length > min_audio_clip_bundel_size) { NeedSep = true; } } else if (fi.Length > min_compress_bundle_size) { option = BuildAssetBundleOptions.DeterministicAssetBundle | BuildAssetBundleOptions.CompleteAssets | BuildAssetBundleOptions.CollectDependencies; suc = BuildPipeline.BuildAssetBundleExplicitAssetNames(new Object[] { realass }, new string[] { "1" }, outfile, option, ExportAssetBundlesHelper.CurBuildTarget); Debug.LogWarning("Big bundle: " + outfile + " Origin Size: " + fi.Length); } } byte[] content = File.ReadAllBytes(outfile); string outfile2 = outpath + "/" + Path.GetFileName(asspath) + ".u3dext"; _depmap[outfile2.ToLower()] = 1; var oldFileInfo = new FileInfo(outfile2); if (oldFileInfo.Exists) { oldFileInfo.IsReadOnly = false; } using (FileStream fs = File.Open(outfile2, FileMode.Create, FileAccess.Write)) { AssetBundleHeader bh = new AssetBundleHeader(); bool bDefault = true; if (ForceSep || NeedSep) { bh.option |= AssetBundleHeader.BundleOption.SepFile; } if (realass is Material) { bh.specialType = AssetBundleHeader.BundleSpecialType.Material; Material mt = realass as Material; if (mt.shader != null) { bDefault = false; List <string> pnames = new List <string>(); int nPCount = ShaderUtil.GetPropertyCount(mt.shader); for (int n = 0; n < nPCount; n++) { ShaderUtil.ShaderPropertyType spt = ShaderUtil.GetPropertyType(mt.shader, n); if (spt == ShaderUtil.ShaderPropertyType.TexEnv) { string pn = ShaderUtil.GetPropertyName(mt.shader, n); pnames.Add(pn); } } List <AssetBundleHeader.DepInfo> deplist = new List <AssetBundleHeader.DepInfo>(); foreach (var realsub in realsubs) { bool findtex = false; foreach (var texname in pnames) { Texture tex = mt.GetTexture(texname); if (tex) { string texpath = AssetDatabase.GetAssetPath(tex); if (!string.IsNullOrEmpty(texpath)) { string realpath = ConvertFileName(texpath) + ".u3dext"; realpath = realpath.ToLower(); if (realpath == realsub) { AssetBundleHeader.DepInfo info = new AssetBundleHeader.DepInfo(); info.name = texname; info.path = realsub; deplist.Add(info); findtex = true; } } } } if (!findtex) { AssetBundleHeader.DepInfo info = new AssetBundleHeader.DepInfo(); info.name = ""; info.path = realsub; deplist.Add(info); } } bh.deps = deplist.ToArray(); } } else if (realass is Texture) { bh.option |= AssetBundleHeader.BundleOption.ManuallyResolve; bh.specialType = AssetBundleHeader.BundleSpecialType.Texture; } else if (realass is Shader) { bh.option |= AssetBundleHeader.BundleOption.DonotRelease; } else if (realass is MonoScript) { bh.option |= AssetBundleHeader.BundleOption.DonotRelease; } else if (realass is Font) { bh.option |= AssetBundleHeader.BundleOption.DonotRelease; } if (bDefault) { bh.deps = new AssetBundleHeader.DepInfo[realsubs.Count]; for (int n = 0; n < realsubs.Count; n++) { bh.deps[n].name = ""; bh.deps[n].path = realsubs[n]; } } bh.Save(fs); fs.Write(content, 0, content.Length); } File.Delete(outfile); } }
public static void DrawAnimatableProperties(SerializedProperty sp, Material[] mats) { bool isClicked; using (new EditorGUILayout.HorizontalScope(GUILayout.ExpandWidth(false))) { var r = EditorGUI.PrefixLabel(EditorGUILayout.GetControlRect(true), new GUIContent(sp.displayName, sp.tooltip)); var text = sp.hasMultipleDifferentValues ? "-" : CollectActiveNames(sp, s_ActiveNames); isClicked = GUI.Button(r, text, EditorStyles.popup); } if (!isClicked) { return; } var gm = new GenericMenu(); gm.AddItem(new GUIContent("Nothing"), s_ActiveNames.Count == 0, () => { sp.ClearArray(); sp.serializedObject.ApplyModifiedProperties(); }); if (!sp.hasMultipleDifferentValues) { for (var i = 0; i < sp.arraySize; i++) { var p = sp.GetArrayElementAtIndex(i); var name = p.FindPropertyRelative("m_Name").stringValue; var type = (ShaderPropertyType)p.FindPropertyRelative("m_Type").intValue; AddMenu(gm, sp, new AnimatedPropertiesEditor { _name = name, _type = type }, false); } } s_Names.Clear(); foreach (var mat in mats) { if (!mat || !mat.shader) { continue; } for (var i = 0; i < ShaderUtil.GetPropertyCount(mat.shader); i++) { var pName = ShaderUtil.GetPropertyName(mat.shader, i); var type = (ShaderPropertyType)ShaderUtil.GetPropertyType(mat.shader, i); var name = string.Format("{0} ({1})", pName, type); if (s_Names.Contains(name)) { continue; } s_Names.Add(name); AddMenu(gm, sp, new AnimatedPropertiesEditor { _name = pName, _type = type }, true); if (type != ShaderPropertyType.Texture) { continue; } AddMenu(gm, sp, new AnimatedPropertiesEditor { _name = pName + "_ST", _type = ShaderPropertyType.Vector }, true); AddMenu(gm, sp, new AnimatedPropertiesEditor { _name = pName + "_HDR", _type = ShaderPropertyType.Vector }, true); AddMenu(gm, sp, new AnimatedPropertiesEditor { _name = pName + "_TexelSize", _type = ShaderPropertyType.Vector }, true); } } gm.ShowAsContext(); }
private static AssetBundleHeader.DepInfo[] CalcMaterialDeps(string assetBundleName, Material material, AssetBundleManifest manifest) { string[] depBundleNames = manifest.GetDirectDependencies(assetBundleName); if (material.shader != null) { List <string> pnames = new List <string>(); int nPCount = ShaderUtil.GetPropertyCount(material.shader); for (int n = 0; n < nPCount; n++) { ShaderUtil.ShaderPropertyType spt = ShaderUtil.GetPropertyType(material.shader, n); if (spt == ShaderUtil.ShaderPropertyType.TexEnv) { string pn = ShaderUtil.GetPropertyName(material.shader, n); pnames.Add(pn); } } List <AssetBundleHeader.DepInfo> deplist = new List <AssetBundleHeader.DepInfo>(); foreach (var depBundleName in depBundleNames) { bool findtex = false; foreach (var texname in pnames) { Texture tex = material.GetTexture(texname); if (tex) { string texpath = AssetDatabase.GetAssetPath(tex); if (!string.IsNullOrEmpty(texpath)) { string texBundleName = AssetPathToBundleName(texpath); if (texBundleName == depBundleName) { AssetBundleHeader.DepInfo info = new AssetBundleHeader.DepInfo(); info.name = texname; info.path = depBundleName + ".u3dext"; deplist.Add(info); findtex = true; } } } } if (!findtex) { AssetBundleHeader.DepInfo info = new AssetBundleHeader.DepInfo(); info.name = ""; info.path = depBundleName + ".u3dext"; deplist.Add(info); } } return(deplist.ToArray()); } else { return(CalcNormalDeps(assetBundleName, material, manifest)); } }
static void CompareUnityMaterial(Material lhs, Material rhs) { Assert.AreEqual(lhs.name, rhs.name); Assert.AreEqual(lhs.shader, rhs.shader); var sb = new StringBuilder(); for (int i = 0; i < ShaderUtil.GetPropertyCount(lhs.shader); ++i) { var prop = ShaderUtil.GetPropertyName(lhs.shader, i); if (s_ignoreProps.Contains(prop)) { continue; } switch (ShaderUtil.GetPropertyType(lhs.shader, i)) { case UnityEditor.ShaderUtil.ShaderPropertyType.Color: case UnityEditor.ShaderUtil.ShaderPropertyType.Vector: { var l = lhs.GetVector(prop); var r = rhs.GetVector(prop); if (l != r) { sb.AppendLine($"{prop} {l}!={r}"); } } break; case UnityEditor.ShaderUtil.ShaderPropertyType.Float: case UnityEditor.ShaderUtil.ShaderPropertyType.Range: { var l = lhs.GetFloat(prop); var r = rhs.GetFloat(prop); if (l != r) { sb.AppendLine($"{prop} {l}!={r}"); } } break; case UnityEditor.ShaderUtil.ShaderPropertyType.TexEnv: { var l = lhs.GetTextureOffset(prop); var r = rhs.GetTextureOffset(prop); if (l != r) { sb.AppendLine($"{prop} {l}!={r}"); } } break; default: throw new NotImplementedException(prop); } } if (sb.Length > 0) { Debug.LogWarning(sb.ToString()); } Assert.AreEqual(0, sb.Length); }
static void WriteMaterial(Material material) { string asset_path = AssetDatabase.GetAssetPath(material); if (asset_path.StartsWith("Assets/")) { asset_path = asset_path.Substring("Assets/".Length); } else { asset_path = asset_path + "." + material.name + ".mat"; } WriteString(asset_path); if (cache.materials.ContainsKey(asset_path)) { return; } cache.materials.Add(asset_path, material); var bw_save = bw; var ms = new MemoryStream(); bw = new BinaryWriter(ms); var shader = material.shader; int property_count = ShaderUtil.GetPropertyCount(shader); WriteString(material.name); WriteString(shader.name); bw.Write(property_count); for (int i = 0; i < property_count; ++i) { var property_name = ShaderUtil.GetPropertyName(shader, i); var property_type = ShaderUtil.GetPropertyType(shader, i); WriteString(property_name); bw.Write((int)property_type); switch (property_type) { case ShaderUtil.ShaderPropertyType.Color: WriteColor32(material.GetColor(property_name)); break; case ShaderUtil.ShaderPropertyType.Vector: WriteVector4(material.GetVector(property_name)); break; case ShaderUtil.ShaderPropertyType.Float: case ShaderUtil.ShaderPropertyType.Range: bw.Write(material.GetFloat(property_name)); break; case ShaderUtil.ShaderPropertyType.TexEnv: var scale = material.GetTextureScale(property_name); var offset = material.GetTextureOffset(property_name); WriteVector4(new Vector4(scale.x, scale.y, offset.x, offset.y)); var texture = material.GetTexture(property_name); if (texture != null) { WriteTexture(texture); } else { WriteString(""); } break; } } string file_path = out_dir + "/" + asset_path; CreateFileDirIfNeed(file_path); File.WriteAllBytes(file_path, ms.ToArray()); bw = bw_save; }
public override void OnInspectorGUI() { MaterialPropertySetter obj = target as MaterialPropertySetter; if (obj == null) { return; } var serialized = new SerializedObject(target); if (serialized == null) { return; } var serializedRenderer = serialized.FindProperty("rend"); obj._updateInEditor = EditorGUILayout.Toggle("Update in edit-mode", obj._updateInEditor); obj._useSharedMaterial = EditorGUILayout.Toggle("Use shared-materials", obj._useSharedMaterial); EditorGUILayout.PropertyField(serializedRenderer, new GUIContent("Renderer: ")); Renderer rend = serializedRenderer.objectReferenceValue as Renderer; Material selectedMaterial = null; if (rend != null) { int selectedMaterialIndex = 0; if (rend.sharedMaterials != null && rend.sharedMaterials.Length > 1) { int materialCount = rend.sharedMaterials.Length; string[] materialSelection = new string[materialCount]; for (int m = 0; m < rend.sharedMaterials.Length; ++m) { materialSelection[m] = rend.sharedMaterials[m] != null ? rend.sharedMaterials[m].name : "NULL_MATERIAL"; } selectedMaterialIndex = Mathf.Max(0, EditorGUILayout.Popup("Material: ", obj.materialIndex, materialSelection)); selectedMaterial = rend.sharedMaterials[obj.materialIndex]; } else if (rend.sharedMaterial != null) { selectedMaterial = rend.sharedMaterial; } serializedObject.FindProperty("materialIndex").intValue = selectedMaterialIndex; obj.materialIndex = selectedMaterialIndex; var serializedPropertyName = serializedObject.FindProperty("propertyName"); if (selectedMaterial != null && serializedRenderer.objectReferenceValue != null) { Shader shader = selectedMaterial.shader; string selectedShaderProp = serializedPropertyName.stringValue; int shaderPropCount = ShaderUtil.GetPropertyCount(shader); List <string> shaderPropertiesList = new List <string>(); for (int sp = 0; sp < shaderPropCount; ++sp) { shaderPropertiesList.Add(ShaderUtil.GetPropertyName(shader, sp)); } bool missingSelectedShaderProp = false; if (!shaderPropertiesList.Contains(selectedShaderProp)) { missingSelectedShaderProp = true; shaderPropertiesList.Add(selectedShaderProp); } GUIContent[] shaderProperties = new GUIContent[shaderPropertiesList.Count]; for (int i = 0; i < shaderProperties.Length; ++i) { string contentPrefix = missingSelectedShaderProp && shaderPropertiesList[i] == selectedShaderProp ? "(MISSING) " : ""; shaderProperties[i] = new GUIContent(contentPrefix + shaderPropertiesList[i]); } int shaderPropIndex = -1; for (int i = 0; i < shaderPropertiesList.Count; ++i) { if (shaderPropertiesList[i] == selectedShaderProp) { shaderPropIndex = i; } } shaderPropIndex = Mathf.Max(0, EditorGUILayout.Popup(new GUIContent("Shader property: "), shaderPropIndex, shaderProperties)); if (shaderPropIndex >= 0 && shaderPropIndex < shaderProperties.Length) { obj.propertyName = shaderPropertiesList[shaderPropIndex]; serializedPropertyName.stringValue = shaderPropertiesList[shaderPropIndex]; } serialized.ApplyModifiedProperties(); if (shaderPropIndex < shaderPropCount) { ShaderUtil.ShaderPropertyType shaderPropType = ShaderUtil.GetPropertyType(shader, shaderPropIndex); var serializedPropertyType = serializedObject.FindProperty("_propertyType"); switch (shaderPropType) { default: case ShaderUtil.ShaderPropertyType.Color: { var serializedColorField = serialized.FindProperty("value_color"); EditorGUILayout.PropertyField(serializedColorField, new GUIContent("Value: ")); obj._propertyType = MaterialPropertySetter.PropertyType.Color; break; } case ShaderUtil.ShaderPropertyType.Range: case ShaderUtil.ShaderPropertyType.Float: { var serializedFloatField = serialized.FindProperty("value_float"); EditorGUILayout.PropertyField(serializedFloatField, new GUIContent("Value: ")); obj._propertyType = MaterialPropertySetter.PropertyType.Float; break; } case ShaderUtil.ShaderPropertyType.TexEnv: { var serializedTextureField = serialized.FindProperty("value_tex"); EditorGUILayout.PropertyField(serializedTextureField, new GUIContent("Value: ")); obj._propertyType = MaterialPropertySetter.PropertyType.Texture; break; } case ShaderUtil.ShaderPropertyType.Vector: { var serializedVectorField = serialized.FindProperty("value_vec4"); serializedVectorField.vector4Value = EditorGUILayout.Vector4Field(new GUIContent("Value: "), serializedVectorField.vector4Value); obj._propertyType = MaterialPropertySetter.PropertyType.Vector; break; } } } } } serialized.ApplyModifiedProperties(); if (obj._updateInEditor) { obj.DoUpdate(); } }
public static void ConvertToNonUMA(GameObject baseObject, UMAAvatarBase avatar, string Folder, bool ConvertNormalMaps, string CharName) { Folder = Folder + "/" + CharName; if (!System.IO.Directory.Exists(Folder)) { System.IO.Directory.CreateDirectory(Folder); } SkinnedMeshRenderer[] renderers = avatar.umaData.GetRenderers(); int meshno = 0; foreach (SkinnedMeshRenderer smr in renderers) { Material[] mats = smr.sharedMaterials; int Material = 0; foreach (Material m in mats) { // get each texture. // if the texture has been generated (has no path) then we need to convert to Texture2D (if needed) save that asset. // update the material with that material. List <Texture> allTexture = new List <Texture>(); Shader shader = m.shader; for (int i = 0; i < ShaderUtil.GetPropertyCount(shader); i++) { if (ShaderUtil.GetPropertyType(shader, i) == ShaderUtil.ShaderPropertyType.TexEnv) { string propertyName = ShaderUtil.GetPropertyName(shader, i); Texture texture = m.GetTexture(propertyName); if (texture is Texture2D || texture is RenderTexture) { string path = AssetDatabase.GetAssetPath(texture.GetInstanceID()); if (string.IsNullOrEmpty(path)) { if (ConvertNormalMaps && propertyName.ToLower().Contains("bumpmap")) { // texture = ConvertNormalMap(texture); texture = sconvertNormalMap(texture); } string texName = Path.Combine(Folder, CharName + "_Mat_" + Material + propertyName + ".png"); SaveTexture(texture, texName); AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport); Texture2D tex = AssetDatabase.LoadAssetAtPath <Texture2D>(CustomAssetUtility.UnityFriendlyPath(texName)); m.SetTexture(propertyName, tex); } } } } string matname = Folder + "/" + CharName + "_Mat_" + Material + ".mat"; CustomAssetUtility.SaveAsset <Material>(m, matname); Material++; // Save the material to disk? // update the SMR } string meshName = Folder + "/" + CharName + "_Mesh_" + meshno + ".asset"; meshno++; // Save Mesh to disk. CustomAssetUtility.SaveAsset <Mesh>(smr.sharedMesh, meshName); smr.sharedMaterials = mats; smr.materials = mats; } // save Animator Avatar. var animator = baseObject.GetComponent <Animator>(); string avatarName = Folder + "/" + CharName + "_Avatar.asset"; CustomAssetUtility.SaveAsset <Avatar>(animator.avatar, avatarName); DestroyImmediate(avatar); var lod = baseObject.GetComponent <UMASimpleLOD>(); if (lod != null) { DestroyImmediate(lod); } var ud = baseObject.GetComponent <UMAData>(); if (ud != null) { DestroyImmediate(ud); } var ue = baseObject.GetComponent <UMAExpressionPlayer>(); if (ue != null) { DestroyImmediate(ue); } baseObject.name = CharName; string prefabName = Folder + "/" + CharName + ".prefab"; prefabName = CustomAssetUtility.UnityFriendlyPath(prefabName); PrefabUtility.SaveAsPrefabAssetAndConnect(baseObject, prefabName, InteractionMode.AutomatedAction); }
IEnumerable <Validation> _Validate(GameObject ExportRoot, VRMExportSettings m_settings) { if (ExportRoot == null) { yield break; } if (DuplicateBoneNameExists(ExportRoot)) { yield return(Validation.Warning(Msg(VRMExporterWizardMessages.DUPLICATE_BONE_NAME_EXISTS))); } if (m_settings.ReduceBlendshape && ExportRoot.GetComponent <VRMBlendShapeProxy>() == null) { yield return(Validation.Error(Msg(VRMExporterWizardMessages.NEEDS_VRM_BLENDSHAPE_PROXY))); } var vertexColor = ExportRoot.GetComponentsInChildren <SkinnedMeshRenderer>().Any(x => x.sharedMesh.colors.Length > 0); if (vertexColor) { yield return(Validation.Warning(Msg(VRMExporterWizardMessages.VERTEX_COLOR_IS_INCLUDED))); } var renderers = ExportRoot.GetComponentsInChildren <Renderer>(); foreach (var r in renderers) { for (int i = 0; i < r.sharedMaterials.Length; ++i) { if (r.sharedMaterials[i] == null) { yield return(Validation.Error($"Renderer: {r.name}.Materials[{i}] is null. please fix it")); } } } var materials = renderers.SelectMany(x => x.sharedMaterials).Where(x => x != null).Distinct(); foreach (var material in materials) { if (material == null) { continue; } if (material.shader.name == "Standard") { // standard continue; } if (VRMMaterialExporter.UseUnlit(material.shader.name)) { // unlit continue; } if (VRMMaterialExporter.VRMExtensionShaders.Contains(material.shader.name)) { // VRM supported continue; } yield return(Validation.Warning($"Material: {material.name}. Unknown Shader: \"{material.shader.name}\" is used. {Msg(VRMExporterWizardMessages.UNKNOWN_SHADER)}")); } foreach (var material in materials) { if (IsFileNameLengthTooLong(material.name)) { yield return(Validation.Error(Msg(VRMExporterWizardMessages.FILENAME_TOO_LONG) + material.name)); } } var textureNameList = new List <string>(); foreach (var material in materials) { var shader = material.shader; int propertyCount = ShaderUtil.GetPropertyCount(shader); for (int i = 0; i < propertyCount; i++) { if (ShaderUtil.GetPropertyType(shader, i) == ShaderUtil.ShaderPropertyType.TexEnv) { if ((material.GetTexture(ShaderUtil.GetPropertyName(shader, i)) != null)) { var textureName = material.GetTexture(ShaderUtil.GetPropertyName(shader, i)).name; if (!textureNameList.Contains(textureName)) { textureNameList.Add(textureName); } } } } } foreach (var textureName in textureNameList) { if (IsFileNameLengthTooLong(textureName)) { yield return(Validation.Error(Msg(VRMExporterWizardMessages.FILENAME_TOO_LONG) + textureName)); } } var vrmMeta = ExportRoot.GetComponent <VRMMeta>(); if (vrmMeta != null && vrmMeta.Meta != null && vrmMeta.Meta.Thumbnail != null) { var thumbnailName = vrmMeta.Meta.Thumbnail.name; if (IsFileNameLengthTooLong(thumbnailName)) { yield return(Validation.Error(Msg(VRMExporterWizardMessages.FILENAME_TOO_LONG) + thumbnailName)); } } var meshFilters = ExportRoot.GetComponentsInChildren <MeshFilter>(); var meshesName = meshFilters.Select(x => x.sharedMesh.name).Distinct(); foreach (var meshName in meshesName) { if (IsFileNameLengthTooLong(meshName)) { yield return(Validation.Error(Msg(VRMExporterWizardMessages.FILENAME_TOO_LONG) + meshName)); } } var skinnedmeshRenderers = ExportRoot.GetComponentsInChildren <SkinnedMeshRenderer>(); var skinnedmeshesName = skinnedmeshRenderers.Select(x => x.sharedMesh.name).Distinct(); foreach (var skinnedmeshName in skinnedmeshesName) { if (IsFileNameLengthTooLong(skinnedmeshName)) { yield return(Validation.Error(Msg(VRMExporterWizardMessages.FILENAME_TOO_LONG) + skinnedmeshName)); } } }
private MetallicRoughnessShaderArguments SetupMetallicRoughnessPBR(Material material) { var arguments = new MetallicRoughnessShaderArguments(); SetupFlags(material, arguments); var shader = material.shader; for (var i = 0; i < ShaderUtil.GetPropertyCount(shader); i++) { var propertyName = ShaderUtil.GetPropertyName(shader, i); var propertyType = ShaderUtil.GetPropertyType(shader, i); switch (propertyType) { case ShaderUtil.ShaderPropertyType.Color: { var color = material.GetColor(propertyName); switch (propertyName) { case "_Color": arguments.BaseColorColor = color; break; case "_EmissionColor": arguments.EmissiveColor = color; break; } break; } case ShaderUtil.ShaderPropertyType.Float: { var value = material.GetFloat(propertyName); switch (propertyName) { case "_BumpScale": arguments.BumpScale = value; break; case "_DetailNormalMapScale": break; case "_DstBlend": break; case "_GlossyReflections": break; case "_Mode": break; case "_SmoothnessTextureChannel": arguments.SmoothnessTextureChannel = (SmoothnessTextureChannel)value; break; case "_SpecularHighlights": break; case "_SrcBlend": break; case "_UVSec": break; case "_ZWrite": break; } break; } case ShaderUtil.ShaderPropertyType.Range: { var value = material.GetFloat(propertyName); switch (propertyName) { case "_Cutoff": arguments.Cutoff = value; break; case "_GlossMapScale": break; case "_Glossiness": arguments.Glossiness = value; break; case "_Metallic": arguments.Metallic = value; break; case "_OcclusionStrength": break; case "_Parallax": break; } break; } case ShaderUtil.ShaderPropertyType.TexEnv: { var texture = material.GetTexture(propertyName); if (texture != null) { switch (propertyName) { case "_BumpMap": arguments.Bump = texture; break; case "_DetailAlbedoMap": arguments.DetailBaseColor = texture; break; case "_DetailMask": arguments.Detail = texture; break; case "_DetailNormalMap": arguments.DetailNormal = texture; break; case "_EmissionMap": arguments.Emission = texture; break; case "_MainTex": arguments.BaseColor = texture; break; case "_MetallicGlossMap": arguments.MetallicGloss = texture; break; case "_OcclusionMap": arguments.Occlusion = texture; break; case "_ParallaxMap": arguments.Parallax = texture; break; } } break; } } } return(arguments); }
public static string CheckMaterial(Material mat, BuildTarget buildTarget) { string result; if (mat == null || mat.shader == null) { result = null; } else { string shaderName = mat.shader.name; int lOD = ShaderUtil.GetLOD(mat.shader); bool flag = Array.Exists <string>(PerformanceChecks.kShadersWithMobileVariants, (string s) => s == shaderName); bool flag2 = PerformanceChecks.IsMobileBuildTarget(buildTarget); if (!(mat.GetTag("PerformanceChecks", true).ToLower() == "false")) { if (flag) { if (flag2 && mat.HasProperty("_Color") && mat.GetColor("_Color") == new Color(1f, 1f, 1f, 1f)) { result = PerformanceChecks.FormattedTextContent("Shader is using white color which does nothing; Consider using {0} shader for performance.", new object[] { "Mobile/" + shaderName }); return(result); } if (flag2 && shaderName.StartsWith("Particles/")) { result = PerformanceChecks.FormattedTextContent("Consider using {0} shader on this platform for performance.", new object[] { "Mobile/" + shaderName }); return(result); } if (shaderName == "RenderFX/Skybox" && mat.HasProperty("_Tint") && mat.GetColor("_Tint") == new Color(0.5f, 0.5f, 0.5f, 0.5f)) { result = PerformanceChecks.FormattedTextContent("Skybox shader is using gray color which does nothing; Consider using {0} shader for performance.", new object[] { "Mobile/Skybox" }); return(result); } } if (lOD >= 300 && flag2 && !shaderName.StartsWith("Mobile/")) { result = PerformanceChecks.FormattedTextContent("Shader might be expensive on this platform. Consider switching to a simpler shader; look under Mobile shaders.", new object[0]); return(result); } if (shaderName.Contains("VertexLit") && mat.HasProperty("_Emission")) { bool flag3 = false; Shader shader = mat.shader; int propertyCount = ShaderUtil.GetPropertyCount(shader); for (int i = 0; i < propertyCount; i++) { if (ShaderUtil.GetPropertyName(shader, i) == "_Emission") { flag3 = (ShaderUtil.GetPropertyType(shader, i) == ShaderUtil.ShaderPropertyType.Color); break; } } if (flag3) { Color color = mat.GetColor("_Emission"); if (color.r >= 0.5f && color.g >= 0.5f && color.b >= 0.5f) { result = PerformanceChecks.FormattedTextContent("Looks like you're using VertexLit shader to simulate an unlit object (white emissive). Use one of Unlit shaders instead for performance.", new object[0]); return(result); } } } if (mat.HasProperty("_BumpMap") && mat.GetTexture("_BumpMap") == null) { result = PerformanceChecks.FormattedTextContent("Normal mapped shader without a normal map. Consider using a non-normal mapped shader for performance.", new object[0]); return(result); } } result = null; } return(result); }
private LegacyShaderArguments SetupLegacy(Material material) { var arguments = new LegacyShaderArguments(); SetupFlags(material, arguments); var shader = material.shader; for (var i = 0; i < ShaderUtil.GetPropertyCount(shader); i++) { var propertyName = ShaderUtil.GetPropertyName(shader, i); var propertyType = ShaderUtil.GetPropertyType(shader, i); switch (propertyType) { case ShaderUtil.ShaderPropertyType.Color: { var color = material.GetColor(propertyName); switch (propertyName) { case "_MainColor": case "_Color": arguments.DiffColor = color; break; case "_EmissionColor": arguments.EmissiveColor = color; break; case "_SpecColor": arguments.SpecColor = color; break; } break; } case ShaderUtil.ShaderPropertyType.Float: { var value = material.GetFloat(propertyName); switch (propertyName) { case "BumpScale": arguments.BumpScale = value; break; case "_DetailNormalMapScale": break; case "_DstBlend": break; case "_GlossyReflections": break; case "_Mode": break; case "_SmoothnessTextureChannel": break; case "_SpecularHighlights": break; case "_SrcBlend": break; case "_UVSec": break; case "_ZWrite": break; case "_Alpha_1": arguments.DiffColor = new Color(arguments.DiffColor.r, arguments.DiffColor.g, arguments.DiffColor.b, value); break; } break; } case ShaderUtil.ShaderPropertyType.Range: { var value = material.GetFloat(propertyName); switch (propertyName) { case "_Cutoff": arguments.Cutoff = value; break; case "_GlossMapScale": break; case "_Glossiness": break; case "_OcclusionStrength": break; case "_Parallax": break; } break; } case ShaderUtil.ShaderPropertyType.TexEnv: { var texture = material.GetTexture(propertyName); switch (propertyName) { case "_Normal": case "_NormalMapRefraction": case "_BumpMap": arguments.Bump = texture; break; case "_DetailMask": arguments.Detail = texture; break; case "_DetailNormalMap": arguments.DetailNormal = texture; break; case "_Emission": case "_EmissionMap": arguments.Emission = texture; break; case "_Diffuse": case "_Texture": case "_MainTexture": case "_MainTex": arguments.Diffuse = texture; break; case "_OcclusionMap": arguments.Occlusion = texture; break; case "_ParallaxMap": arguments.Parallax = texture; break; case "_SpecGlossMap": case "_SpecularRGBGlossA": arguments.Specular = texture; break; } break; } } } return(arguments); }
public static MaterialDatabase BuildMaterialDatabase(MaterialReference[] materialReferences) { if (true || materialReferences == null) { return(new MaterialDatabase(new MaterialInfo[0], new MaterialPropertyInfo[0])); } MaterialInfo[] materialInfos = new MaterialInfo[materialReferences.Length]; int totalPropertyCount = 0; for (int i = 0; i < materialReferences.Length; i++) { Shader shader = materialReferences[i].material.shader; int count = ShaderUtil.GetPropertyCount(shader); materialInfos[i] = new MaterialInfo() { material = materialReferences[i].material, materialName = materialReferences[i].name, propertyRange = new RangeInt(totalPropertyCount, count) }; totalPropertyCount += count; } MaterialPropertyInfo[] propertyInfos = new MaterialPropertyInfo[totalPropertyCount]; int idx = 0; for (int i = 0; i < materialReferences.Length; i++) { Material material = materialReferences[i].material; Shader shader = material.shader; int count = materialInfos[i].propertyRange.length; for (int j = 0; j < count; j++) { ShaderUtil.ShaderPropertyType type = ShaderUtil.GetPropertyType(shader, j); string propertyName = ShaderUtil.GetPropertyName(shader, j); // todo -- use string intern system to handle names instead MaterialPropertyValue materialValue = new MaterialPropertyValue { shaderPropertyId = Shader.PropertyToID(propertyName), propertyType = ConvertPropertyType(type) }; switch (type) { case ShaderUtil.ShaderPropertyType.Color: materialValue.colorValue = material.GetColor(materialValue.shaderPropertyId); break; case ShaderUtil.ShaderPropertyType.Vector: materialValue.vectorValue = material.GetVector(materialValue.shaderPropertyId); break; case ShaderUtil.ShaderPropertyType.Float: materialValue.floatValue = material.GetFloat(materialValue.shaderPropertyId); break; case ShaderUtil.ShaderPropertyType.Range: break; case ShaderUtil.ShaderPropertyType.TexEnv: materialValue.texture = material.GetTexture(materialValue.shaderPropertyId); break; default: throw new ArgumentOutOfRangeException(); } propertyInfos[idx++] = new MaterialPropertyInfo() { propertyName = propertyName, propertyType = ConvertPropertyType(type), propertyId = Shader.PropertyToID(propertyName) }; } } return(new MaterialDatabase(materialInfos, propertyInfos)); }
public override void OnImportAsset(AssetImportContext ctx) { string sceneName = null; GameObject gltfScene = null; UnityEngine.Mesh[] meshes = null; try { sceneName = Path.GetFileNameWithoutExtension(ctx.assetPath); gltfScene = CreateGLTFScene(ctx.assetPath); // Remove empty roots if (_removeEmptyRootObjects) { var t = gltfScene.transform; while ( gltfScene.transform.childCount == 1 && gltfScene.GetComponents <Component>().Length == 1) { var parent = gltfScene; gltfScene = gltfScene.transform.GetChild(0).gameObject; t = gltfScene.transform; t.parent = null; // To keep transform information in the new parent Object.DestroyImmediate(parent); // Get rid of the parent } } // Ensure there are no hide flags present (will cause problems when saving) gltfScene.hideFlags &= ~(HideFlags.HideAndDontSave); foreach (Transform child in gltfScene.transform) { child.gameObject.hideFlags &= ~(HideFlags.HideAndDontSave); } // Zero position gltfScene.transform.position = Vector3.zero; // Get meshes var meshNames = new List <string>(); var meshHash = new HashSet <UnityEngine.Mesh>(); var meshFilters = gltfScene.GetComponentsInChildren <MeshFilter>(); var vertexBuffer = new List <Vector3>(); meshes = meshFilters.Select(mf => { var mesh = mf.sharedMesh; vertexBuffer.Clear(); mesh.GetVertices(vertexBuffer); for (var i = 0; i < vertexBuffer.Count; ++i) { vertexBuffer[i] *= _scaleFactor; } mesh.SetVertices(vertexBuffer); if (_swapUvs) { var uv = mesh.uv; var uv2 = mesh.uv2; mesh.uv = uv2; mesh.uv2 = uv2; } if (_importNormals == GLTFImporterNormals.None) { mesh.normals = new Vector3[0]; } if (_importNormals == GLTFImporterNormals.Calculate) { mesh.RecalculateNormals(); } mesh.UploadMeshData(!_readWriteEnabled); if (_generateColliders) { var collider = mf.gameObject.AddComponent <MeshCollider>(); collider.sharedMesh = mesh; } if (meshHash.Add(mesh)) { var meshName = string.IsNullOrEmpty(mesh.name) ? mf.gameObject.name : mesh.name; mesh.name = ObjectNames.GetUniqueName(meshNames.ToArray(), meshName); meshNames.Add(mesh.name); } return(mesh); }).ToArray(); var renderers = gltfScene.GetComponentsInChildren <Renderer>(); if (_importMaterials) { // Get materials var materialNames = new List <string>(); var materialHash = new HashSet <UnityEngine.Material>(); var materials = renderers.SelectMany(r => { return(r.sharedMaterials.Select(mat => { if (materialHash.Add(mat)) { var matName = string.IsNullOrEmpty(mat.name) ? mat.shader.name : mat.name; if (matName == mat.shader.name) { matName = matName.Substring(Mathf.Min(matName.LastIndexOf("/") + 1, matName.Length - 1)); } // Ensure name is unique matName = string.Format("{0} {1}", sceneName, ObjectNames.NicifyVariableName(matName)); matName = ObjectNames.GetUniqueName(materialNames.ToArray(), matName); mat.name = matName; materialNames.Add(matName); } return mat; })); }).ToArray(); // Get textures var textureNames = new List <string>(); var textureHash = new HashSet <Texture2D>(); var texMaterialMap = new Dictionary <Texture2D, List <TexMaterialMap> >(); var textures = materials.SelectMany(mat => { var shader = mat.shader; if (!shader) { return(Enumerable.Empty <Texture2D>()); } var matTextures = new List <Texture2D>(); for (var i = 0; i < ShaderUtil.GetPropertyCount(shader); ++i) { if (ShaderUtil.GetPropertyType(shader, i) == ShaderUtil.ShaderPropertyType.TexEnv) { var propertyName = ShaderUtil.GetPropertyName(shader, i); var tex = mat.GetTexture(propertyName) as Texture2D; if (tex) { if (textureHash.Add(tex)) { var texName = tex.name; if (string.IsNullOrEmpty(texName)) { if (propertyName.StartsWith("_")) { texName = propertyName.Substring(Mathf.Min(1, propertyName.Length - 1)); } } // Ensure name is unique texName = string.Format("{0} {1}", sceneName, ObjectNames.NicifyVariableName(texName)); texName = ObjectNames.GetUniqueName(textureNames.ToArray(), texName); tex.name = texName; textureNames.Add(texName); matTextures.Add(tex); } List <TexMaterialMap> materialMaps; if (!texMaterialMap.TryGetValue(tex, out materialMaps)) { materialMaps = new List <TexMaterialMap>(); texMaterialMap.Add(tex, materialMaps); } materialMaps.Add(new TexMaterialMap(mat, propertyName, propertyName == "_BumpMap")); } } } return(matTextures); }).ToArray(); var folderName = Path.GetDirectoryName(ctx.assetPath); // Save textures as separate assets and rewrite refs // TODO: Support for other texture types if (textures.Length > 0) { var texturesRoot = string.Concat(folderName, "/", "Textures/"); Directory.CreateDirectory(texturesRoot); foreach (var tex in textures) { var ext = _useJpgTextures ? ".jpg" : ".png"; var texPath = string.Concat(texturesRoot, tex.name, ext); File.WriteAllBytes(texPath, _useJpgTextures ? tex.EncodeToJPG() : tex.EncodeToPNG()); AssetDatabase.ImportAsset(texPath); } } // Save materials as separate assets and rewrite refs if (materials.Length > 0) { var materialRoot = string.Concat(folderName, "/", "Materials/"); Directory.CreateDirectory(materialRoot); foreach (var mat in materials) { var materialPath = string.Concat(materialRoot, mat.name, ".mat"); var newMat = mat; CopyOrNew(mat, materialPath, m => { // Fix references newMat = m; foreach (var r in renderers) { var sharedMaterials = r.sharedMaterials; for (var i = 0; i < sharedMaterials.Length; ++i) { var sharedMaterial = sharedMaterials[i]; if (sharedMaterial.name == mat.name) { sharedMaterials[i] = m; } } sharedMaterials = sharedMaterials.Where(sm => sm).ToArray(); r.sharedMaterials = sharedMaterials; } }); // Fix textures // HACK: This needs to be a delayed call. // Unity needs a frame to kick off the texture import so we can rewrite the ref if (textures.Length > 0) { EditorApplication.delayCall += () => { for (var i = 0; i < textures.Length; ++i) { var tex = textures[i]; var texturesRoot = string.Concat(folderName, "/", "Textures/"); var ext = _useJpgTextures ? ".jpg" : ".png"; var texPath = string.Concat(texturesRoot, tex.name, ext); // Grab new imported texture var materialMaps = texMaterialMap[tex]; var importer = (TextureImporter)TextureImporter.GetAtPath(texPath); var importedTex = AssetDatabase.LoadAssetAtPath <Texture2D>(texPath); if (importer != null) { var isNormalMap = false; foreach (var materialMap in materialMaps) { if (materialMap.Material == mat) { isNormalMap |= materialMap.IsNormalMap; newMat.SetTexture(materialMap.Property, importedTex); } } ; if (isNormalMap) { // Try to auto-detect normal maps importer.textureType = TextureImporterType.NormalMap; } else if (importer.textureType == TextureImporterType.Sprite) { // Force disable sprite mode, even for 2D projects importer.textureType = TextureImporterType.Default; } importer.SaveAndReimport(); } else { Debug.LogWarning(string.Format("GLTFImporter: Unable to import texture at path: {0}", texPath)); } } }; } } } } else { var temp = GameObject.CreatePrimitive(PrimitiveType.Plane); temp.SetActive(false); var defaultMat = new[] { temp.GetComponent <Renderer>().sharedMaterial }; DestroyImmediate(temp); foreach (var rend in renderers) { rend.sharedMaterials = defaultMat; } } } catch { if (gltfScene) { DestroyImmediate(gltfScene); } throw; } #if UNITY_2017_3_OR_NEWER // Set main asset ctx.AddObjectToAsset("main asset", gltfScene); // Add meshes foreach (var mesh in meshes) { ctx.AddObjectToAsset("mesh " + mesh.name, mesh); } ctx.SetMainObject(gltfScene); #else // Set main asset ctx.SetMainAsset("main asset", gltfScene); // Add meshes foreach (var mesh in meshes) { ctx.AddSubAsset("mesh " + mesh.name, mesh); } #endif }
public static IEnumerable <Validation> Validate(GameObject ExportRoot) { var renderers = ExportRoot.GetComponentsInChildren <Renderer>(); var materials = renderers.SelectMany(x => x.sharedMaterials).Where(x => x != null).Distinct(); foreach (var material in materials) { if (IsFileNameLengthTooLong(material.name)) { yield return(Validation.Error(ValidationMessages.FILENAME_TOO_LONG.Msg() + material.name)); } } var textureNameList = new List <string>(); foreach (var material in materials) { var shader = material.shader; int propertyCount = ShaderUtil.GetPropertyCount(shader); for (int i = 0; i < propertyCount; i++) { if (ShaderUtil.GetPropertyType(shader, i) == ShaderUtil.ShaderPropertyType.TexEnv) { if ((material.GetTexture(ShaderUtil.GetPropertyName(shader, i)) != null)) { var textureName = material.GetTexture(ShaderUtil.GetPropertyName(shader, i)).name; if (!textureNameList.Contains(textureName)) { textureNameList.Add(textureName); } } } } } foreach (var textureName in textureNameList) { if (IsFileNameLengthTooLong(textureName)) { yield return(Validation.Error(ValidationMessages.FILENAME_TOO_LONG.Msg() + textureName)); } } var meshFilters = ExportRoot.GetComponentsInChildren <MeshFilter>(); var meshesName = meshFilters.Select(x => x.sharedMesh.name).Distinct(); foreach (var meshName in meshesName) { if (IsFileNameLengthTooLong(meshName)) { yield return(Validation.Error(ValidationMessages.FILENAME_TOO_LONG.Msg() + meshName)); } } var skinnedmeshRenderers = ExportRoot.GetComponentsInChildren <SkinnedMeshRenderer>(); var skinnedmeshesName = skinnedmeshRenderers.Select(x => x.sharedMesh.name).Distinct(); foreach (var skinnedmeshName in skinnedmeshesName) { if (IsFileNameLengthTooLong(skinnedmeshName)) { yield return(Validation.Error(ValidationMessages.FILENAME_TOO_LONG.Msg() + skinnedmeshName)); } } }
static public ComponentDetail CreateDetail(Object obj, AssetFinderWindow assetFinder) { GameObject go = obj as GameObject; List <DetailButton> detailButtonList = new List <DetailButton>(); if (assetFinder.assetType == MATERIALS) { foreach (Renderer renderer in go.GetComponents <Renderer>()) { foreach (Material mat in renderer.sharedMaterials) { if (mat == assetFinder.filterMaterial) { GUIContent guiContent = EditorGUIUtility.ObjectContent(renderer, typeof(Renderer)); guiContent.tooltip = renderer.GetType().Name; detailButtonList.Add(new DetailButton(guiContent)); break; } } } } else if (assetFinder.assetType == TEXTURES) { foreach (Renderer renderer in go.GetComponents <Renderer>()) { foreach (Material mat in renderer.sharedMaterials) { if (mat != null) { Material material = mat; //Second reference to material that won't change and will be used by the delegate. Shader s = material.shader; if (!s.name.StartsWith(assetFinder.shaderName)) { continue; } int propCount = ShaderUtil.GetPropertyCount(s); for (int i = 0; i < propCount; i++) { if (ShaderUtil.GetPropertyType(s, i) == ShaderUtil.ShaderPropertyType.TexEnv) { string propName = ShaderUtil.GetPropertyName(s, i); if ((assetFinder.materialPropertyName.Equals("") || assetFinder.materialPropertyName.Equals(propName)) && material.HasProperty(propName)) { Texture texture = material.GetTexture(propName); if (texture == assetFinder.filterTexture) { GUIContent guiContent = EditorGUIUtility.ObjectContent(renderer, typeof(Renderer)); guiContent.tooltip = material.name + "(" + propName + ")"; detailButtonList.Add(new DetailButton(EditorGUIUtility.ObjectContent(renderer, typeof(Renderer)), delegate() { EditorGUIUtility.PingObject(material); } )); break; } } } } } } } } else if (assetFinder.assetType == MESHES) { MeshFilter mf = go.GetComponent <MeshFilter>(); if (mf != null && mf.sharedMesh == assetFinder.filterMesh) { GUIContent guiContent = EditorGUIUtility.ObjectContent(mf, typeof(MeshFilter)); guiContent.tooltip = mf.GetType().Name; detailButtonList.Add(new DetailButton(guiContent)); } SkinnedMeshRenderer smr = go.GetComponent <SkinnedMeshRenderer>(); if (smr != null && smr.sharedMesh == assetFinder.filterMesh) { GUIContent guiContent = EditorGUIUtility.ObjectContent(smr, typeof(SkinnedMeshRenderer)); guiContent.tooltip = smr.GetType().Name; detailButtonList.Add(new DetailButton(guiContent)); } foreach (MeshCollider mc in go.GetComponents <MeshCollider>()) { if (mc.sharedMesh == assetFinder.filterMesh) { GUIContent guiContent = EditorGUIUtility.ObjectContent(mc, typeof(MeshCollider)); guiContent.tooltip = mc.GetType().Name; detailButtonList.Add(new DetailButton(guiContent)); } } } return(new ComponentDetail(go, detailButtonList.ToArray())); }