public static MeshInfo[] MeshesInfoFromGameObject(GameObject gameObject) { // Associate all renderers and materials to an asset // An asset is composed of at least one Mesh // It will fail if one asset is rendered multiple times in the game object hierarchy Dictionary <string, MeshInfo> meshesInfo = new Dictionary <string, MeshInfo>(); foreach (Renderer rendererCandidate in gameObject.GetComponentsInChildren <Renderer>()) { Mesh foundMesh = null; if (rendererCandidate is MeshRenderer) { // A MeshRenderer defines materials to apply on a Mesh // It implies there is a MeshFilter on the same GameObject referencing the Mesh MeshFilter meshFilter = rendererCandidate.GetComponent <MeshFilter>(); if (meshFilter != null) { foundMesh = meshFilter.sharedMesh; } } if (rendererCandidate is SkinnedMeshRenderer) { // A SkinnedMeshRenderer defines materials to apply on a Mesh and references it foundMesh = ((SkinnedMeshRenderer)rendererCandidate).sharedMesh; } if (foundMesh == null) { continue; } string assetPath = AssetDatabase.GetAssetPath(foundMesh); Material[] materials = rendererCandidate.sharedMaterials.ToList() .Where(m => m != null && ShadersInfos.ContainsShader(m.shader)) .ToArray(); if (materials.Length == 0) { continue; } if (!meshesInfo.ContainsKey(assetPath)) { meshesInfo.Add(assetPath, new MeshInfo { AssetPath = assetPath }); } meshesInfo[assetPath].AddMaterials(materials); meshesInfo[assetPath].Identifier = gameObject.GetInstanceID(); } return(meshesInfo.Values.ToArray()); }
private static JSONNode GetSpDataLinkToSend(MeshInfo meshInfo, string substancePainterProjectPath) { // Prepare data to send to SP string workspacePath = Path.GetDirectoryName(Application.dataPath); string meshPath = Path.GetFullPath(Path.Combine(workspacePath, meshInfo.AssetPath).ToString()); string exportPath = Path.Combine(Path.Combine("Assets", "SP_Textures"), Path.GetFileNameWithoutExtension(meshInfo.AssetPath)).ToString(); string meshUri = new System.Uri(meshPath).AbsoluteUri; JSONClass materialsLink = new JSONClass(); foreach (Material material in meshInfo.Materials) { ShaderInfos shaderInfos = ShadersInfos.GetShaderInfos(material.shader); JSONClass propertiesAssociation = new JSONClass(); foreach (string propertyName in shaderInfos.PropertiesAssociation.Keys) { propertiesAssociation.Add(propertyName, new JSONData(shaderInfos.PropertiesAssociation[propertyName])); } JSONClass materialLink = new JSONClass(); materialLink.Add("assetPath", AssetDatabase.GetAssetPath(material)); materialLink.Add("exportPreset", shaderInfos.ExportPreset); materialLink.Add("resourceShader", shaderInfos.ResourceShader); materialLink.Add("spToLiveLinkProperties", propertiesAssociation); // HACK: Sanitize the name the same way SP internally do it string sanitizedName = MaterialsManipulation.SanitizeMaterialName(material.name); materialsLink.Add(sanitizedName, materialLink); } JSONClass project = new JSONClass(); project.Add("meshUrl", new JSONData(meshUri)); project.Add("normal", new JSONData("OpenGL")); project.Add("template", new JSONData("")); project.Add("url", new JSONData(new System.Uri(substancePainterProjectPath).AbsoluteUri)); JSONClass jsonData = new JSONClass(); jsonData.Add("applicationName", new JSONData("Unity")); jsonData.Add("exportPath", new JSONData(exportPath)); jsonData.Add("workspacePath", new JSONData(workspacePath)); jsonData.Add("materials", materialsLink); jsonData.Add("project", project); jsonData.Add("linkIdentifier", new JSONData(meshInfo.Identifier)); return(jsonData); }
private static void SendMeshToSP(MeshInfo meshInfo) { if (!webSocket.IsAlive) { ConnectSocket(); } if (!webSocket.IsAlive || !webSocket.Ping()) { EditorUtility.DisplayDialog( "Send to Substance Painter", "Substance Painter is not detected.\n" + "Please check if Substance Painter is correctly started and if the \"unity-link\" plugin is enabled.", "OK"); return; } // Ensure compatibility foreach (Material material in meshInfo.Materials) { if (ShadersInfos.ContainsShader(material.shader)) { ShadersInfos.GetShaderInfos(material.shader).EnsureMaterialCompatibility(material); } } // Check if a project already exist string substancePainterProjectPath = GetSpProjectPath(meshInfo); if (File.Exists(substancePainterProjectPath)) { // If the project exists, open it then reimport the mesh Debug.Log(string.Format("Reopening Substance Painter project located at {0}", substancePainterProjectPath)); OpenSpProject(meshInfo, substancePainterProjectPath); } else { // If the project doesn't exist, create a new one and save it here Debug.Log(string.Format("Creating a new Substance Painter project located at {0}", substancePainterProjectPath)); CreateSpProject(meshInfo, substancePainterProjectPath); } }
public static bool SetMaterialParam(Material material, string property, JSONNode valueNode) { int propertyIndex; if (!CheckMaterialProperty(material, property, out propertyIndex)) { return(false); } // Set the property value bool succeed = false; ShaderUtil.ShaderPropertyType type = ShaderUtil.GetPropertyType(material.shader, propertyIndex); switch (type) { case ShaderUtil.ShaderPropertyType.TexEnv: succeed = SetMaterialTexture(material, property, valueNode); break; default: Debug.LogWarning(string.Format("{0} property exchange not implemented", type.ToString())); break; } if (!succeed) { Debug.LogWarning(string.Format("Failed to load property '{0}' value of type {1} on material {2}: {3}", property, type.ToString(), AssetDatabase.GetAssetPath(material), valueNode.Value)); } else { // Apply property changed post process ShaderInfos shaderInfos = ShadersInfos.GetShaderInfos(material.shader); if (shaderInfos.PostProcesses.ContainsKey(property)) { shaderInfos.PostProcesses[property](material, valueNode); } } return(succeed); }
private static bool CheckMaterialProperty(Material material, string property, out int propertyIndex) { propertyIndex = -1; // Check parameter validity ShaderInfos shaderInfos = ShadersInfos.GetShaderInfos(material.shader); if (shaderInfos == null || !shaderInfos.PropertiesAssociation.ContainsValue(property)) { Debug.LogWarning(string.Format("Unknown '{0}' parameter in shader {1}", property, material.shader.name)); return(false); } int propertyCount = ShaderUtil.GetPropertyCount(material.shader); for (int i = 0; i < propertyCount; ++i) { if (ShaderUtil.GetPropertyName(material.shader, i).Equals(property)) { propertyIndex = i; return(true); } } Debug.LogWarning(string.Format("Material '{0}' doesn't contain '{1}' property", AssetDatabase.GetAssetPath(material), property)); return(false); }