398 lines
20 KiB
C#

#if !LILTOON_VRCSDK3_AVATARS && !LILTOON_VRCSDK3_WORLDS && VRC_SDK_VRCSDK3
#if UDON
#define LILTOON_VRCSDK3_WORLDS
#else
#define LILTOON_VRCSDK3_AVATARS
#endif
#endif
#if UNITY_EDITOR
using UnityEditor;
using UnityEngine;
using UnityEngine.Rendering;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Reflection;
using Object = UnityEngine.Object;
namespace lilToon
{
public partial class lilToonInspector
{
//------------------------------------------------------------------------------------------------------------------------------
// GUI
#region
// For custom shader
public static bool Foldout(string title, bool display) { return lilEditorGUI.Foldout(title, display); }
public static bool Foldout(string title, string help, bool display) { return lilEditorGUI.Foldout(title, help, display); }
public static void DrawLine() { lilEditorGUI.DrawLine(); }
private static void ToggleGUI(string label, ref bool value) { value = EditorGUILayout.ToggleLeft(label, value); }
private void OpenHelpPage(object helpAnchor) { Application.OpenURL(GetLoc("sManualURL") + helpAnchor); }
private static void DrawWebPages()
{
VersionCheck();
var labelStyle = new GUIStyle(GUI.skin.label){fontStyle = FontStyle.Bold};
string versionLabel = "lilToon " + lilConstants.currentVersionName;
if(latestVersion != null && latestVersion.latest_vertion_name != null && latestVersion.latest_vertion_value > lilConstants.currentVersionValue)
{
versionLabel = "[Update] lilToon " + lilConstants.currentVersionName + " -> " + latestVersion.latest_vertion_name;
labelStyle.normal.textColor = Color.red;
}
edSet.isShowWebPages = lilEditorGUI.DrawSimpleFoldout(versionLabel, edSet.isShowWebPages, labelStyle, isCustomEditor);
if(edSet.isShowWebPages)
{
EditorGUI.indentLevel++;
lilEditorGUI.DrawWebButton("BOOTH", lilConstants.boothURL);
lilEditorGUI.DrawWebButton("GitHub", lilConstants.githubURL);
EditorGUI.indentLevel--;
}
}
private static void VersionCheck()
{
if(string.IsNullOrEmpty(latestVersion.latest_vertion_name))
{
if(!string.IsNullOrEmpty(lilEditorParameters.instance.versionInfo))
{
if(
!string.IsNullOrEmpty(lilEditorParameters.instance.versionInfo) &&
lilEditorParameters.instance.versionInfo.Contains("latest_vertion_name") &&
lilEditorParameters.instance.versionInfo.Contains("latest_vertion_value")
)
{
EditorJsonUtility.FromJsonOverwrite(lilEditorParameters.instance.versionInfo, latestVersion);
return;
}
}
latestVersion.latest_vertion_name = lilConstants.currentVersionName;
latestVersion.latest_vertion_value = lilConstants.currentVersionValue;
return;
}
}
private static void DrawHelpPages()
{
edSet.isShowHelpPages = lilEditorGUI.DrawSimpleFoldout(GetLoc("sHelp"), edSet.isShowHelpPages, isCustomEditor);
if(edSet.isShowHelpPages)
{
EditorGUI.indentLevel++;
lilEditorGUI.DrawWebButton(GetLoc("sCommonProblems"), GetLoc("sReadmeURL") + GetLoc("sReadmeAnchorProblem"));
EditorGUI.indentLevel--;
}
}
private static void DrawShaderTypeWarn(Material material)
{
if(!isMultiVariants && material.shader.name.Contains("Overlay") && lilEditorGUI.AutoFixHelpBox(GetLoc("sHelpSelectOverlay")))
{
material.shader = lts;
}
}
private static void SelectEditorMode()
{
string[] sEditorModeList = {GetLoc("sEditorModeSimple"),GetLoc("sEditorModeAdvanced"),GetLoc("sEditorModePreset"),GetLoc("sEditorModeShaderSetting")};
edSet.editorMode = (EditorMode)GUILayout.Toolbar((int)edSet.editorMode, sEditorModeList);
}
private void DrawMenuButton(string helpAnchor, PropertyBlock propertyBlock)
{
var position = GUILayoutUtility.GetLastRect();
position.x += position.width - 24;
position.width = 24;
if(GUI.Button(position, EditorGUIUtility.IconContent("_Popup"), middleButton))
{
var menu = new GenericMenu();
menu.AddItem(new GUIContent(GetLoc("sCopy")), false, CopyProperties, propertyBlock);
menu.AddItem(new GUIContent(GetLoc("sPaste")), false, PasteProperties, new PropertyBlockData{propertyBlock = propertyBlock, shouldCopyTex = false});
menu.AddItem(new GUIContent(GetLoc("sPasteWithTexture")), false, PasteProperties, new PropertyBlockData{propertyBlock = propertyBlock, shouldCopyTex = true});
#if UNITY_2019_3_OR_NEWER
menu.AddItem(new GUIContent(GetLoc("sReset")), false, ResetProperties, propertyBlock);
#endif
menu.AddItem(new GUIContent(GetLoc("sOpenManual")), false, OpenHelpPage, helpAnchor);
menu.ShowAsContext();
}
}
private void DrawVRCFallbackGUI(Material material)
{
#if VRC_SDK_VRCSDK2 || LILTOON_VRCSDK3_AVATARS || LILTOON_VRCSDK3_WORLDS
edSet.isShowVRChat = lilEditorGUI.Foldout("VRChat", "VRChat", edSet.isShowVRChat);
if(edSet.isShowVRChat)
{
EditorGUILayout.BeginVertical(boxOuter);
string tag = material.GetTag("VRCFallback", false);
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = m_MaterialEditor.targets.Where(obj => obj is Material).Any(obj => tag != ((Material)obj).GetTag("VRCFallback", false));
bool shouldSetTag = EditorGUI.ToggleLeft(EditorGUILayout.GetControlRect(), "Custom Safety Fallback", !string.IsNullOrEmpty(tag), customToggleFont);
if(shouldSetTag)
{
EditorGUILayout.BeginVertical(boxInnerHalf);
string[] sFallbackShaderTypes = {"Unlit", "Standard", "VertexLit", "Toon", "Particle", "Sprite", "Matcap", "MobileToon", "Hidden"};
string[] sFallbackRenderTypes = {"Opaque", "Cutout", "Transparent", "Fade"};
string[] sFallbackCullTypes = {"Default", "DoubleSided"};
int fallbackShaderType = tag.Contains("Standard") ? 1 : 0;
fallbackShaderType = tag.Contains("VertexLit") ? 2 : fallbackShaderType;
fallbackShaderType = tag.Contains("Toon") ? 3 : fallbackShaderType;
fallbackShaderType = tag.Contains("Particle") ? 4 : fallbackShaderType;
fallbackShaderType = tag.Contains("Sprite") ? 5 : fallbackShaderType;
fallbackShaderType = tag.Contains("Matcap") ? 6 : fallbackShaderType;
fallbackShaderType = tag.Contains("MobileToon") ? 7 : fallbackShaderType;
fallbackShaderType = tag.Contains("Hidden") ? 8 : fallbackShaderType;
int fallbackRenderType = tag.Contains("Cutout") ? 1 : 0;
fallbackRenderType = tag.Contains("Transparent") ? 2 : fallbackRenderType;
fallbackRenderType = tag.Contains("Fade") ? 3 : fallbackRenderType;
int fallbackCullType = tag.Contains("DoubleSided") ? 1 : 0;
fallbackShaderType = lilEditorGUI.Popup("Shader Type", fallbackShaderType, sFallbackShaderTypes);
fallbackRenderType = lilEditorGUI.Popup("Rendering Mode", fallbackRenderType, sFallbackRenderTypes);
fallbackCullType = lilEditorGUI.Popup("Facing", fallbackCullType, sFallbackCullTypes);
switch(fallbackShaderType)
{
case 0: tag = "Unlit"; break;
case 1: tag = "Standard"; break;
case 2: tag = "VertexLit"; break;
case 3: tag = "Toon"; break;
case 4: tag = "Particle"; break;
case 5: tag = "Sprite"; break;
case 6: tag = "Matcap"; break;
case 7: tag = "MobileToon"; break;
case 8: tag = "Hidden"; break;
default: tag = "Unlit"; break;
}
switch(fallbackRenderType)
{
case 0: break;
case 1: tag += "Cutout"; break;
case 2: tag += "Transparent"; break;
case 3: tag += "Fade"; break;
default: break;
}
switch(fallbackCullType)
{
case 0: break;
case 1: tag += "DoubleSided"; break;
default: break;
}
EditorGUILayout.LabelField("Result:", '"' + tag + '"');
EditorGUILayout.EndVertical();
}
else
{
tag = "";
}
EditorGUI.showMixedValue = false;
if(EditorGUI.EndChangeCheck())
{
foreach(var obj in m_MaterialEditor.targets.Where(obj => obj is Material))
{
((Material)obj).SetOverrideTag("VRCFallback", tag);
EditorUtility.SetDirty(obj);
}
AssetDatabase.SaveAssets();
}
EditorGUILayout.EndVertical();
}
#endif
}
private void DrawOptimizationButton(Material material, bool isnormal)
{
#if LILTOON_VRCSDK3_WORLDS
if(isnormal && lilEditorGUI.Button(GetLoc("sOptimizeForEvents"))) lilMaterialUtils.RemoveUnusedTexture(material);
#endif
}
#endregion
//------------------------------------------------------------------------------------------------------------------------------
// Editor
#region
private void CheckShaderType(Material material)
{
isLite = material.shader.name.Contains("Lite");
isCutout = material.shader.name.Contains("Cutout");
isTransparent = material.shader.name.Contains("Transparent") || material.shader.name.Contains("Overlay");
isOutl = !isMultiVariants && material.shader.name.Contains("Outline");
isRefr = !isMultiVariants && material.shader.name.Contains("Refraction");
isBlur = !isMultiVariants && material.shader.name.Contains("Blur");
isFur = !isMultiVariants && material.shader.name.Contains("Fur");
isTess = !isMultiVariants && material.shader.name.Contains("Tessellation");
isGem = !isMultiVariants && material.shader.name.Contains("Gem");
isFakeShadow = !isMultiVariants && material.shader.name.Contains("FakeShadow");
isOnePass = material.shader.name.Contains("OnePass");
isTwoPass = material.shader.name.Contains("TwoPass");
isMulti = material.shader.name.Contains("Multi");
isCustomShader = material.shader.name.Contains("Optional");
isShowRenderMode = !isCustomShader;
isStWr = stencilPass.floatValue == (float)StencilOp.Replace;
renderingModeBuf = RenderingMode.Opaque;
if(isCutout) renderingModeBuf = RenderingMode.Cutout;
if(isTransparent) renderingModeBuf = RenderingMode.Transparent;
if(isRefr) renderingModeBuf = RenderingMode.Refraction;
if(isRefr && isBlur) renderingModeBuf = RenderingMode.RefractionBlur;
if(isFur) renderingModeBuf = RenderingMode.Fur;
if(isFur && isCutout) renderingModeBuf = RenderingMode.FurCutout;
if(isFur && isTwoPass) renderingModeBuf = RenderingMode.FurTwoPass;
if(isGem) renderingModeBuf = RenderingMode.Gem;
transparentModeBuf = TransparentMode.Normal;
if(isOnePass) transparentModeBuf = TransparentMode.OnePass;
if(!isFur && isTwoPass) transparentModeBuf = TransparentMode.TwoPass;
float tpmode = 0.0f;
if(material.HasProperty("_TransparentMode")) tpmode = material.GetFloat("_TransparentMode");
isUseAlpha =
renderingModeBuf == RenderingMode.Cutout ||
renderingModeBuf == RenderingMode.Transparent ||
renderingModeBuf == RenderingMode.Fur ||
renderingModeBuf == RenderingMode.FurCutout ||
renderingModeBuf == RenderingMode.FurTwoPass ||
(isMulti && tpmode != 0.0f && tpmode != 3.0f && tpmode != 6.0f);
if(isMulti)
{
isCutout = tpmode == 1.0f || tpmode == 5.0f;
isTransparent = tpmode == 2.0f;
}
}
private void CopyProperties(PropertyBlock propertyBlock)
{
foreach(var p in AllProperties().Where(p =>
p.p != null &&
p.blocks.Contains(propertyBlock)
))
{
copiedProperties[p.name] = p.p;
}
}
private void PasteProperties(PropertyBlock propertyBlock, bool shouldCopyTex)
{
foreach(var p in AllProperties().Where(p =>
p.p != null &&
p.blocks.Contains(propertyBlock) &&
!(!shouldCopyTex && p.isTexture) &&
copiedProperties.ContainsKey(p.name) &&
copiedProperties[p.name] != null
))
{
var propType = p.type;
if(propType == MaterialProperty.PropType.Color) p.colorValue = copiedProperties[p.name].colorValue;
if(propType == MaterialProperty.PropType.Vector) p.vectorValue = copiedProperties[p.name].vectorValue;
if(propType == MaterialProperty.PropType.Float) p.floatValue = copiedProperties[p.name].floatValue;
if(propType == MaterialProperty.PropType.Range) p.floatValue = copiedProperties[p.name].floatValue;
if(propType == MaterialProperty.PropType.Texture) p.textureValue = copiedProperties[p.name].textureValue;
}
}
private void ResetProperties(PropertyBlock propertyBlock)
{
#if UNITY_2019_3_OR_NEWER
foreach(var p in AllProperties().Where(p =>
p.p != null &&
p.blocks.Contains(propertyBlock) &&
p.targets[0] is Material &&
((Material)p.targets[0]).shader != null
))
{
var shader = ((Material)p.targets[0]).shader;
int propID = shader.FindPropertyIndex(p.name);
if(propID == -1) continue;
var propType = p.type;
if(propType == MaterialProperty.PropType.Color) p.colorValue = shader.GetPropertyDefaultVectorValue(propID);
if(propType == MaterialProperty.PropType.Vector) p.vectorValue = shader.GetPropertyDefaultVectorValue(propID);
if(propType == MaterialProperty.PropType.Float) p.floatValue = shader.GetPropertyDefaultFloatValue(propID);
if(propType == MaterialProperty.PropType.Range) p.floatValue = shader.GetPropertyDefaultFloatValue(propID);
if(propType == MaterialProperty.PropType.Texture) p.textureValue = null;
}
#endif
}
private bool ShouldDrawBlock(PropertyBlock propertyBlock)
{
if(propertyBlock == PropertyBlock.Base && lilEditorGUI.CheckPropertyToDraw("Render Queue")) return true;
if(propertyBlock == PropertyBlock.Rendering && lilEditorGUI.CheckPropertyToDraw("Render Queue", "Enable GPU Instancing")) return true;
foreach (var p in GetBlock2Properties()[propertyBlock])
{
if (p.p == null ) { continue; }
if (lilEditorGUI.CheckPropertyToDraw(p) is false) { continue; }
return true;
}
return false;
}
private bool ShouldDrawBlock(params string[] labels)
{
return lilEditorGUI.CheckPropertyToDraw(labels);
}
private bool ShouldDrawBlock()
{
return lilEditorGUI.CheckPropertyToDraw();
}
private void CopyProperties(object obj)
{
CopyProperties((PropertyBlock)obj);
}
private void PasteProperties(object obj)
{
var propertyBlockData = (PropertyBlockData)obj;
PasteProperties(propertyBlockData.propertyBlock, propertyBlockData.shouldCopyTex);
}
private void ResetProperties(object obj)
{
ResetProperties((PropertyBlock)obj);
}
private void ApplyLightingPreset(LightingPreset lightingPreset)
{
switch(lightingPreset)
{
case LightingPreset.Default:
if(asUnlit.p != null) asUnlit.floatValue = shaderSetting.defaultAsUnlit;
if(vertexLightStrength.p != null) vertexLightStrength.floatValue = shaderSetting.defaultVertexLightStrength;
if(lightMinLimit.p != null) lightMinLimit.floatValue = shaderSetting.defaultLightMinLimit;
if(lightMaxLimit.p != null) lightMaxLimit.floatValue = shaderSetting.defaultLightMaxLimit;
if(beforeExposureLimit.p != null) beforeExposureLimit.floatValue = shaderSetting.defaultBeforeExposureLimit;
if(monochromeLighting.p != null) monochromeLighting.floatValue = shaderSetting.defaultMonochromeLighting;
if(shadowEnvStrength.p != null) shadowEnvStrength.floatValue = 0.0f;
if(lilDirectionalLightStrength.p != null) lilDirectionalLightStrength.floatValue = shaderSetting.defaultlilDirectionalLightStrength;
break;
case LightingPreset.SemiMonochrome:
if(asUnlit.p != null) asUnlit.floatValue = 0.0f;
if(vertexLightStrength.p != null) vertexLightStrength.floatValue = 0.0f;
if(lightMinLimit.p != null) lightMinLimit.floatValue = 0.05f;
if(lightMaxLimit.p != null) lightMaxLimit.floatValue = 1.0f;
if(beforeExposureLimit.p != null) beforeExposureLimit.floatValue = 10000.0f;
if(monochromeLighting.p != null) monochromeLighting.floatValue = 0.5f;
if(shadowEnvStrength.p != null) shadowEnvStrength.floatValue = 0.0f;
if(lilDirectionalLightStrength.p != null) lilDirectionalLightStrength.floatValue = 1.0f;
break;
}
}
#endregion
}
}
#endif