398 lines
20 KiB
C#
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
|