205 lines
7.1 KiB
C#
205 lines
7.1 KiB
C#
using System.IO;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
|
|
//-----------------------------------------------------------------------
|
|
// Author: Colby-O
|
|
// File: PSXMaterialFactory.cs
|
|
//-----------------------------------------------------------------------
|
|
namespace ColbyO.VNTG.PSX.Editor
|
|
{
|
|
public static class PSXMaterialFactory
|
|
{
|
|
private const string PSX_SHADER_NAME = "VNTG/PSXMaster_URP";
|
|
private const string PSX_TERRIAN_SHADER_NAME = "VNTG/PSXTerrian_URP";
|
|
private const string PSX_WATER_SHADER_NAME = "VNTG/PSXWater_URP";
|
|
private const string PSX_DECAL_SHADER_NAME = "VNTG/PSXDecal_URP";
|
|
private const string PSX_SKYBOX_SHADER_NAME = "VNTG/PSXSkybox_URP";
|
|
|
|
[MenuItem("Assets/Create/VNTG/PSX Material", false)]
|
|
public static void CreatePSXMaterial()
|
|
{
|
|
CreateMateral(PSX_SHADER_NAME);
|
|
}
|
|
|
|
#if UNITY_6000_3_OR_NEWER
|
|
[MenuItem("Assets/Create/VNTG/PSX Terrian Material", false)]
|
|
public static void CreateTerrianMaterial()
|
|
{
|
|
CreateMateral(PSX_TERRIAN_SHADER_NAME);
|
|
}
|
|
#endif
|
|
|
|
[MenuItem("Assets/Create/VNTG/PSX Water Material", false)]
|
|
public static void CreateWaterMaterial()
|
|
{
|
|
CreateMateral(PSX_WATER_SHADER_NAME);
|
|
}
|
|
|
|
[MenuItem("Assets/Create/VNTG/PSX Decal Material", false)]
|
|
public static void CreateDecalMaterial()
|
|
{
|
|
CreateMateral(PSX_DECAL_SHADER_NAME);
|
|
}
|
|
|
|
[MenuItem("Assets/Create/VNTG/PSX Skybox Material", false)]
|
|
public static void CreateSkyboxMaterial()
|
|
{
|
|
CreateMateral(PSX_SKYBOX_SHADER_NAME);
|
|
}
|
|
|
|
[MenuItem("Assets/VNTG/Convert to PSX Material", false)]
|
|
public static void ConvertToPSXMaterial()
|
|
{
|
|
Material selectedMaterial = Selection.activeObject as Material;
|
|
|
|
Shader psxShader = Shader.Find(PSX_SHADER_NAME);
|
|
if (psxShader == null)
|
|
{
|
|
Debug.LogError($"PSXFactory: Could not find shader: '{PSX_SHADER_NAME}'.");
|
|
return;
|
|
}
|
|
|
|
string originalShaderName = selectedMaterial.shader.name;
|
|
bool isLit = false;
|
|
|
|
if (originalShaderName.Contains("Lit") && !originalShaderName.Contains("Unlit"))
|
|
{
|
|
isLit = true;
|
|
}
|
|
|
|
string texturePropertyName = "_MainTex";
|
|
Vector2 originalTiling = Vector2.one;
|
|
Vector2 originalOffset = Vector2.zero;
|
|
|
|
if (selectedMaterial.HasProperty(texturePropertyName))
|
|
{
|
|
originalTiling = selectedMaterial.GetTextureScale(texturePropertyName);
|
|
originalOffset = selectedMaterial.GetTextureOffset(texturePropertyName);
|
|
}
|
|
|
|
float originalCutoff = 0.5f;
|
|
bool isAlphaClipEnabled = false;
|
|
|
|
if (selectedMaterial.HasProperty("_Cutoff"))
|
|
{
|
|
originalCutoff = selectedMaterial.GetFloat("_Cutoff");
|
|
}
|
|
|
|
if (selectedMaterial.IsKeywordEnabled("_ALPHATEST_ON"))
|
|
{
|
|
isAlphaClipEnabled = true;
|
|
}
|
|
|
|
bool receiveShadows = true;
|
|
|
|
if (selectedMaterial.IsKeywordEnabled("_RECEIVE_SHADOWS_OFF"))
|
|
{
|
|
receiveShadows = false;
|
|
}
|
|
else if (selectedMaterial.HasProperty("_ReceiveShadows"))
|
|
{
|
|
receiveShadows = selectedMaterial.GetFloat("_ReceiveShadows") == 1.0f;
|
|
}
|
|
|
|
float originalSmoothness = 0.0f;
|
|
|
|
if (selectedMaterial.HasProperty("_Smoothness"))
|
|
{
|
|
originalSmoothness = selectedMaterial.GetFloat("_Smoothness");
|
|
}
|
|
else if (selectedMaterial.HasProperty("_Glossiness"))
|
|
{
|
|
originalSmoothness = selectedMaterial.GetFloat("_Glossiness");
|
|
}
|
|
|
|
float originalMetallic = 0.0f;
|
|
if (selectedMaterial.HasProperty("_Metallic"))
|
|
{
|
|
originalMetallic = selectedMaterial.GetFloat("_Metallic");
|
|
}
|
|
|
|
Undo.RecordObject(selectedMaterial, "Convert Material to PSX");
|
|
|
|
selectedMaterial.shader = psxShader;
|
|
|
|
if (isLit)
|
|
{
|
|
selectedMaterial.SetLightingMethod(PSXLightingMethod.Lit);
|
|
selectedMaterial.SetFloat("_UseSpecular", 1.0f);
|
|
selectedMaterial.SetFloat("_Smoothness", originalSmoothness);
|
|
selectedMaterial.SetFloat("_Metalness", originalMetallic);
|
|
}
|
|
else
|
|
{
|
|
selectedMaterial.SetLightingMethod(PSXLightingMethod.Unlit);
|
|
}
|
|
|
|
selectedMaterial.SetVector("_Tiling", originalTiling);
|
|
selectedMaterial.SetVector("_Offset", originalOffset);
|
|
|
|
selectedMaterial.SetFloat("_AlphaClipThreshold", isAlphaClipEnabled ? originalCutoff : 0.0f);
|
|
|
|
selectedMaterial.SetFloat("_EnableShadows", receiveShadows ? 1.0f : 0.0f);
|
|
|
|
|
|
EditorUtility.SetDirty(selectedMaterial);
|
|
AssetDatabase.SaveAssets();
|
|
|
|
Debug.Log($"Successfully converted '{selectedMaterial.name}' to PSX shader.", selectedMaterial);
|
|
}
|
|
|
|
[MenuItem("Assets/VNTG/Convert to PSX Material", true)]
|
|
public static bool ValidateConvertToPSXMaterial()
|
|
{
|
|
if (Selection.activeObject is Material mat)
|
|
{
|
|
return mat.shader.name != PSX_SHADER_NAME;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private static string GetDefaultMaterialName(string shaderName)
|
|
{
|
|
return shaderName switch
|
|
{
|
|
"VNTG/PSXMaster_URP" => "New PSX Material",
|
|
"VNTG/PSXTerrian_URP" => "New PSX Terrain Material",
|
|
"VNTG/PSXWater_URP" => "New PSX Water Material",
|
|
"VNTG/PSXDecal_URP" => "New PSX Decal Material",
|
|
"VNTG/PSXSkybox_URP" => "New PSX Skybox Material",
|
|
_ => "New Material"
|
|
};
|
|
}
|
|
|
|
private static void CreateMateral(string shaderName)
|
|
{
|
|
string path = AssetDatabase.GetAssetPath(Selection.activeObject);
|
|
if (string.IsNullOrEmpty(path))
|
|
{
|
|
path = "Assets";
|
|
}
|
|
else if (!Directory.Exists(path))
|
|
{
|
|
path = Path.GetDirectoryName(path);
|
|
}
|
|
|
|
string fullPath = Path.Combine(path, $"{GetDefaultMaterialName(shaderName)}.mat");
|
|
fullPath = AssetDatabase.GenerateUniqueAssetPath(fullPath);
|
|
|
|
Shader psxShader = Shader.Find(shaderName);
|
|
if (psxShader == null)
|
|
{
|
|
Debug.LogError($"PSXFactory: Could not find shader: '{shaderName}'. Please check the shader path string in the script.");
|
|
return;
|
|
}
|
|
|
|
Material newMat = new Material(psxShader);
|
|
AssetDatabase.CreateAsset(newMat, fullPath);
|
|
AssetDatabase.SaveAssets();
|
|
|
|
EditorUtility.FocusProjectWindow();
|
|
Selection.activeObject = newMat;
|
|
}
|
|
}
|
|
} |