当前位置:网站首页>Unity map auto match material tool map auto add to shader tool shader match map tool map made by substance painter auto match shader tool
Unity map auto match material tool map auto add to shader tool shader match map tool map made by substance painter auto match shader tool
2022-07-07 12:06:00 【Tang Zhe】
Powerful Unity Editor Extension
Some of you might ask : The model is made , Decompress the map first in the model settings , Just unzip the material ?
Certainly. , But now the problem is that the model has no mapping , Maps are in SP Made in , The exported maps are all separate maps , It will not be directly bound to the model
All in all , It's no problem for you to paste one by one on the shader , I think it's too painful , I have to post a model … Post a der.
Editor extension can solve many manual problems .
Look at the effect :
The shader will automatically match the map
Pay attention when matching maps :
The map name must be : The model name _ Shader name _ Map type
Property introduction
- Model path : Dragging the model will automatically identify the path
- Map suffix : similar _Albedo perhaps _Occlusion, Some students like to name it like this ,AL,AO, So open it and customize
- Export shaders : The directory where the model exists will be automatically created Material Folder , Models that do not unzip materials will unzip materials to this folder
- Set the material : Automatically match the map according to the name of the model and shader
SP Export process :
file - Export map - The configuration needs to be named like this
among :
- $project It is the present. SP Project name ( In less than )
- $mesh Is the model name
- $textureSet Is the shader name
Code Introduction :
Attribute here, you can modify the default suffix
[SerializeField]
public string m_Albedo = "_Albedo", m_Metallic = "_Metallic", m_NormalMap = "_Normal", m_HeightMap = "_Height", m_OcclusionMap = "_Occlusion";
Set the name rule here :objName + “_” + mat.name + m_Albedo, Can be modified by yourself
void setMaterialShader(string path)
{
Material mat = AssetDatabase.LoadAssetAtPath<Material>(path);
string[] allPath = GetObjPath("Texture2D");
for (int i = 0, len = allPath.Length; i < len; i++)
{
string filePath = AssetDatabase.GUIDToAssetPath(allPath[i]);
Texture2D t = AssetDatabase.LoadAssetAtPath<Texture2D>(filePath);
string objName = Path.GetFileName(modelPath);
objName = objName.Substring(0, objName.Length - 4);
if (t.name == objName + "_" + mat.name + m_Albedo)
{
mat.SetTexture(Albedo, t);
}
else if (t.name == objName + "_" + mat.name + m_HeightMap)
{
mat.SetTexture(HeightMap, t);
}
else if (t.name == objName + "_" + mat.name + m_Metallic)
{
mat.SetTexture(Metallic, t);
}
else if (t.name == objName + "_" + mat.name + m_NormalMap)
{
mat.SetTexture(NormalMap, t);
}
else if (t.name == objName + "_" + mat.name + m_OcclusionMap)
{
mat.SetTexture(OcclusionMap, t);
}
else
{
Debug.Log(mat.name+" Shaders cannot match :" + t.name);
}
}
}
Complete code :
This code inherits EditorWindow
So we have to put it in Editor Under the folder , Make revolving door And Camera controller Is the same , All use Editor Extension Technology
using System.IO;
using UnityEngine;
using UnityEditor;
public class MatchinMaterial_Editor : EditorWindow
{
public string modelPath = "Assets";
public Rect modelRect;
public string Albedo = "_MainTex";
public string Metallic = "_MetallicGlossMap";
public string NormalMap = "_BumpMap";
public string HeightMap = "_ParallaxMap";
public string OcclusionMap = "_OcclusionMap";
private static MatchinMaterial_Editor _window;
[SerializeField]
public string m_Albedo = "_Albedo", m_Metallic = "_Metallic", m_NormalMap = "_Normal", m_HeightMap = "_Height", m_OcclusionMap = "_Occlusion";
[MenuItem("Tools/ Material matching ")]
public static void showWindow()
{
Rect wr = new Rect(0, 0, 300, 300);
// true Indicates that you cannot dock
_window = (MatchinMaterial_Editor)GetWindowWithRect(typeof(MatchinMaterial_Editor), wr, true, " Material matching ");
_window.Show();
}
public void OnGUI()
{
EditorGUILayout.Space();
EditorGUILayout.LabelField(" Model path ( Drag the folder here with the mouse )");
EditorGUILayout.Space();
GUI.SetNextControlName("input1");// Set the name of the next control
modelRect = EditorGUILayout.GetControlRect();
modelPath = EditorGUI.TextField(modelRect, modelPath);
EditorGUILayout.Space();
m_Albedo = EditorGUILayout.TextField("Albedo Picture suffix ", m_Albedo);
m_Metallic = EditorGUILayout.TextField("Metallic Picture suffix ", m_Metallic);
m_NormalMap = EditorGUILayout.TextField("NormalMap Picture suffix ", m_NormalMap);
m_HeightMap = EditorGUILayout.TextField("HeightMap Picture suffix ", m_HeightMap);
m_OcclusionMap = EditorGUILayout.TextField("OcclusionMap Picture suffix ", m_OcclusionMap);
DragFolder();
EditorGUILayout.Space();
// Export materials
if (GUILayout.Button(" Export shaders "))
{
ForEachModels();
}
EditorGUILayout.Space();
if (GUILayout.Button(" Set the material "))
{
ForEachMaterials();
}
}
/// <summary>
/// Get the drag file
/// </summary>
void DragFolder()
{
// The mouse is in the current window
if (mouseOverWindow == this)
{
// Drag into the window without releasing the mouse
if (Event.current.type == EventType.DragUpdated)
{
DragAndDrop.visualMode = DragAndDropVisualMode.Generic;// Change the appearance of the mouse
// Judgment area
if (modelRect.Contains(Event.current.mousePosition))
GUI.FocusControl("input1");
}
// Drag into the window and release the mouse
else if (Event.current.type == EventType.DragExited)
{
string dragPath = string.Join("", DragAndDrop.paths);
// Judgment area
if (modelRect.Contains(Event.current.mousePosition))
this.modelPath = dragPath;
// Remove focus ( Otherwise GUI Not refresh )
GUI.FocusControl(null);
}
}
}
/// <summary>
/// Export materials
/// </summary>
void ForEachModels()
{
string[] allPath = AssetDatabase.FindAssets("t:GameObject", new string[] {
modelPath });
//Debug.Log("-- allPath: " + allPath.Length);
for (int i = 0, len = allPath.Length; i < len; i++)
{
string filePath = AssetDatabase.GUIDToAssetPath(allPath[i]);
// Set up the model
ExtractMaterialsFromFBX(filePath);
}
// If you choose FBX Model file
if (allPath.Length == 0)
{
if (Path.GetExtension(modelPath) == ".fbx")
{
ExtractMaterialsFromFBX(modelPath);
}
else
{
Debug.LogError(" The currently selected directory cannot be found FBX file : " + this.modelPath);
}
}
}
/// <summary>
/// Export shaders
/// </summary>
/// <param name="assetPath"></param>
public void ExtractMaterialsFromFBX(string assetPath)
{
// Material catalog
string materialFolder = Path.GetDirectoryName(assetPath) + "/Material";
//Debug.Log(assetPath);
// If the folder does not exist, create a new
if (!AssetDatabase.IsValidFolder(materialFolder))
AssetDatabase.CreateFolder(Path.GetDirectoryName(assetPath), "Material");
// obtain assetPath All resources under .
Object[] assets = AssetDatabase.LoadAllAssetsAtPath(assetPath);
foreach (Object item in assets)
{
if (item.GetType() == typeof(Material))
{
string path = System.IO.Path.Combine(materialFolder, item.name) + ".mat";
// Create a new unique path for the resource .
path = AssetDatabase.GenerateUniqueAssetPath(path);
// By importing resources ( for example ,FBX file ) Extract external resources , In object ( for example , texture of material ) Create this resource in .
string value = AssetDatabase.ExtractAsset(item, path);
// Successfully extracted ( If Unity Successfully extracted resources , Then return an empty string )
if (string.IsNullOrEmpty(value))
{
AssetDatabase.WriteImportSettingsIfDirty(assetPath);
AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate);
Debug.Log(Path.GetFileName(assetPath) + " Of Material Export succeeded !!");
}
}
}
}
/// <summary>
/// Get all shaders
/// </summary>
void ForEachMaterials()
{
string[] allPath = GetObjPath("Material");
for (int i = 0, len = allPath.Length; i < len; i++)
{
string filePath = AssetDatabase.GUIDToAssetPath(allPath[i]);
setMaterialShader(filePath);
}
Debug.Log("Material Shader Setup completed , altogether : " + allPath.Length + " individual ");
}
void setMaterialShader(string path)
{
Material mat = AssetDatabase.LoadAssetAtPath<Material>(path);
string[] allPath = GetObjPath("Texture2D");
for (int i = 0, len = allPath.Length; i < len; i++)
{
string filePath = AssetDatabase.GUIDToAssetPath(allPath[i]);
Texture2D t = AssetDatabase.LoadAssetAtPath<Texture2D>(filePath);
string objName = Path.GetFileName(modelPath);
objName = objName.Substring(0, objName.Length - 4);
if (t.name == objName + "_" + mat.name + m_Albedo)
{
mat.SetTexture(Albedo, t);
}
else if (t.name == objName + "_" + mat.name + m_HeightMap)
{
mat.SetTexture(HeightMap, t);
}
else if (t.name == objName + "_" + mat.name + m_Metallic)
{
mat.SetTexture(Metallic, t);
}
else if (t.name == objName + "_" + mat.name + m_NormalMap)
{
mat.SetTexture(NormalMap, t);
}
else if (t.name == objName + "_" + mat.name + m_OcclusionMap)
{
mat.SetTexture(OcclusionMap, t);
}
else
{
Debug.Log(mat.name+" Shaders cannot match :" + t.name);
}
}
}
string[] GetObjPath(string mType)
{
//string path = Path.GetDirectoryName(modelPath) + "/Material";// Get the file directory of this object , Specific to the Material file
string path = Path.GetDirectoryName(modelPath);// Get the file directory of this object
return AssetDatabase.FindAssets("t:"+ mType, new string[] {
path });// Look under this file "t:Material" This file
}
}
This code needs Demo demonstration ?
边栏推荐
- @Bean与@Component用在同一个类上,会怎么样?
- The function of adding @ before the path in C #
- [extraction des caractéristiques de texture] extraction des caractéristiques de texture de l'image LBP basée sur le mode binaire local de Matlab [y compris le code source de Matlab 1931]
- Programming examples of stm32f1 and stm32subeide -315m super regenerative wireless remote control module drive
- Test the foundation of development, and teach you to prepare for a fully functional web platform environment
- 全球首堆“玲龙一号”反应堆厂房钢制安全壳上部筒体吊装成功
- Completion report of communication software development and Application
- Enclosed please find. Net Maui's latest learning resources
- Internet Protocol
- Summed up 200 Classic machine learning interview questions (with reference answers)
猜你喜欢
<No. 8> 1816. 截断句子 (简单)
Common locking table processing methods in Oracle
Swiftui tutorial how to realize automatic scrolling function in 2 seconds
Detailed explanation of debezium architecture of debezium synchronization
超标量处理器设计 姚永斌 第9章 指令执行 摘录
Stm32f1 and stm32subeide programming example -max7219 drives 8-bit 7-segment nixie tube (based on SPI)
Solve the problem that vscode can only open two tabs
In SQL, I want to set foreign keys. Why is this problem
What development models did you know during the interview? Just read this one
112. Network security penetration test - [privilege promotion article 10] - [Windows 2003 lpk.ddl hijacking rights lifting & MSF local rights lifting]
随机推荐
STM32F1与STM32CubeIDE编程实例-MAX7219驱动8位7段数码管(基于SPI)
Flet教程之 17 Card卡片组件 基础入门(教程含源码)
[filter tracking] strapdown inertial navigation simulation based on MATLAB [including Matlab source code 1935]
开发一个小程序商城需要多少钱?
About how to install mysql8.0 on the cloud server (Tencent cloud here) and enable local remote connection
[data clustering] realize data clustering analysis based on multiverse optimization DBSCAN with matlab code
超标量处理器设计 姚永斌 第10章 指令提交 摘录
Cmu15445 (fall 2019) project 2 - hash table details
Onedns helps college industry network security
When sink is consumed in mysql, the self incrementing primary key has been set in the database table. How to operate in Flink?
PowerShell cs-utf-16le code goes online
What are the technical differences in source code anti disclosure
Flet教程之 15 GridView 基础入门(教程含源码)
【滤波跟踪】基于matlab扩展卡尔曼滤波EKF和无迹卡尔曼滤波UKF比较【含Matlab源码 1933期】
Fleet tutorial 14 basic introduction to listtile (tutorial includes source code)
What is a LAN domain name? How to parse?
Flet教程之 18 Divider 分隔符组件 基础入门(教程含源码)
通过环境变量将 Pod 信息呈现给容器
In my limited software testing experience, a full-time summary of automation testing experience
Flet教程之 19 VerticalDivider 分隔符组件 基础入门(教程含源码)