470 lines
11 KiB
C#
470 lines
11 KiB
C#
using System.Collections.Generic;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
|
|
namespace AllIn13DShader
|
|
{
|
|
[System.Serializable]
|
|
public class MaterialOverrideData : ScriptableObject
|
|
{
|
|
public class MaterialOverride
|
|
{
|
|
public Material sourceMaterial;
|
|
public Material previewMaterial;
|
|
|
|
public MaterialOverride(Material sourceMaterial)
|
|
{
|
|
this.sourceMaterial = sourceMaterial;
|
|
|
|
if(sourceMaterial == null)
|
|
{
|
|
this.previewMaterial = null;
|
|
}
|
|
else
|
|
{
|
|
this.previewMaterial = new Material(sourceMaterial);
|
|
this.previewMaterial.name = this.previewMaterial.name + "_PREVIEW";
|
|
}
|
|
}
|
|
|
|
public void ApplyPreviewToSource()
|
|
{
|
|
sourceMaterial.CopyMatchingPropertiesFromMaterial(previewMaterial);
|
|
}
|
|
|
|
|
|
public bool ApplySourceToPreview()
|
|
{
|
|
bool res = true;
|
|
|
|
if (previewMaterial == null || sourceMaterial == null)
|
|
{
|
|
res = false;
|
|
}
|
|
else
|
|
{
|
|
previewMaterial.CopyMatchingPropertiesFromMaterial(sourceMaterial);
|
|
}
|
|
|
|
return res;
|
|
}
|
|
}
|
|
|
|
public class RendererOverride
|
|
{
|
|
public Renderer renderer;
|
|
public MaterialOverride[] materialsOverrides;
|
|
|
|
public Material[] sourceMaterials;
|
|
public Material[] previewMaterials;
|
|
|
|
public RendererOverride(Renderer renderer)
|
|
{
|
|
this.renderer = renderer;
|
|
this.materialsOverrides = new MaterialOverride[renderer.sharedMaterials.Length];
|
|
|
|
sourceMaterials = new Material[materialsOverrides.Length];
|
|
previewMaterials = new Material[materialsOverrides.Length];
|
|
|
|
for (int i = 0; i < materialsOverrides.Length; i++)
|
|
{
|
|
materialsOverrides[i] = new MaterialOverride(renderer.sharedMaterials[i]);
|
|
sourceMaterials[i] = materialsOverrides[i].sourceMaterial;
|
|
previewMaterials[i] = materialsOverrides[i].previewMaterial;
|
|
}
|
|
}
|
|
|
|
public void UsePreviewMaterials()
|
|
{
|
|
if (renderer != null)
|
|
{
|
|
renderer.sharedMaterials = previewMaterials;
|
|
}
|
|
}
|
|
|
|
public void UseMaterialSource()
|
|
{
|
|
if (renderer != null)
|
|
{
|
|
renderer.sharedMaterials = sourceMaterials;
|
|
}
|
|
}
|
|
|
|
public void ApplyPreviewMaterial()
|
|
{
|
|
for (int i = 0; i < materialsOverrides.Length; i++)
|
|
{
|
|
materialsOverrides[i].ApplyPreviewToSource();
|
|
renderer.sharedMaterials[i] = materialsOverrides[i].sourceMaterial;
|
|
}
|
|
}
|
|
|
|
public void DiscardChanges()
|
|
{
|
|
renderer.hideFlags = HideFlags.None;
|
|
UseMaterialSource();
|
|
}
|
|
|
|
public Material[] GetPreviewMaterials()
|
|
{
|
|
return previewMaterials;
|
|
}
|
|
|
|
public void CleanPreviewMaterials()
|
|
{
|
|
for(int i = 0; i < materialsOverrides.Length; i++)
|
|
{
|
|
MaterialOverride matOverride = materialsOverrides[i];
|
|
|
|
matOverride.ApplySourceToPreview();
|
|
|
|
string[] keywords = new string[matOverride.sourceMaterial.shaderKeywords.Length];
|
|
matOverride.sourceMaterial.shaderKeywords.CopyTo(keywords, 0);
|
|
|
|
matOverride.previewMaterial.shaderKeywords = keywords;
|
|
}
|
|
}
|
|
}
|
|
|
|
public enum ApplyTarget
|
|
{
|
|
CURRENT_SCENE,
|
|
SELECTED_FOLDERS,
|
|
ALL_PROJECT,
|
|
}
|
|
|
|
public List<AbstractEffectOverride> effectOverrides;
|
|
public List<PropertyOverride> generalPropertiesOverrides;
|
|
|
|
public RendererOverride[] rendererOverrides;
|
|
|
|
public ApplyTarget applyTarget;
|
|
|
|
[SerializeField] private Object[] folders;
|
|
|
|
public void Initialize()
|
|
{
|
|
ResetData();
|
|
}
|
|
|
|
public void ResetData()
|
|
{
|
|
effectOverrides = new List<AbstractEffectOverride>();
|
|
generalPropertiesOverrides = new List<PropertyOverride>();
|
|
|
|
rendererOverrides = new RendererOverride[0];
|
|
applyTarget = ApplyTarget.CURRENT_SCENE;
|
|
}
|
|
|
|
public void CreateRendererOverride()
|
|
{
|
|
Renderer[] renderers = FindObjectsByType<Renderer>(FindObjectsSortMode.None);
|
|
for (int i = 0; i < renderers.Length; i++)
|
|
{
|
|
if (renderers[i] is ParticleSystemRenderer) { continue; }
|
|
if (renderers[i].sharedMaterial == null) { continue; }
|
|
|
|
|
|
renderers[i].hideFlags = HideFlags.NotEditable;
|
|
RendererOverride rendererOverride = new RendererOverride(renderers[i]);
|
|
ArrayUtility.Add(ref rendererOverrides, rendererOverride);
|
|
}
|
|
}
|
|
|
|
public List<Material> CollectAffectedMaterials()
|
|
{
|
|
List<Material> res = new List<Material>();
|
|
|
|
switch (applyTarget)
|
|
{
|
|
case ApplyTarget.SELECTED_FOLDERS:
|
|
CollectAffectedMaterialsOnSelectedFolders(res);
|
|
break;
|
|
case ApplyTarget.CURRENT_SCENE:
|
|
CollectAffectedMaterialsOnCurrentScene(res);
|
|
break;
|
|
case ApplyTarget.ALL_PROJECT:
|
|
CollectAffectedMaterialsAllProject(res);
|
|
break;
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
public void UsePreviewMaterials()
|
|
{
|
|
for (int i = 0; i < rendererOverrides.Length; i++)
|
|
{
|
|
rendererOverrides[i].UsePreviewMaterials();
|
|
}
|
|
}
|
|
|
|
public void UseMaterialSource()
|
|
{
|
|
for (int i = 0; i < rendererOverrides.Length; i++)
|
|
{
|
|
rendererOverrides[i].UseMaterialSource();
|
|
}
|
|
}
|
|
|
|
public void EndOverrideProcess()
|
|
{
|
|
for (int i = 0; i < rendererOverrides.Length; i++)
|
|
{
|
|
if (rendererOverrides[i].renderer == null) { continue; }
|
|
|
|
rendererOverrides[i].DiscardChanges();
|
|
}
|
|
|
|
//for(int i = 0; i < rendererOverrides.Length; i++)
|
|
//{
|
|
// rendererOverrides[i].renderer.hideFlags = HideFlags.None;
|
|
//}
|
|
|
|
//UseMaterialSource();
|
|
|
|
effectOverrides = new List<AbstractEffectOverride>();
|
|
rendererOverrides = new RendererOverride[0];
|
|
}
|
|
|
|
public void ApplyChangesToMaterials(Material[] materials)
|
|
{
|
|
for (int i = 0; i < materials.Length; i++)
|
|
{
|
|
ApplyChangesToMaterial(materials[i]);
|
|
}
|
|
}
|
|
|
|
public void ApplyChangesToMaterials(List<Material> materials)
|
|
{
|
|
for(int i = 0; i < materials.Count; i++)
|
|
{
|
|
ApplyChangesToMaterial(materials[i]);
|
|
}
|
|
}
|
|
|
|
public void ApplyChangesToMaterial(Material mat)
|
|
{
|
|
for (int i = 0; i < effectOverrides.Count; i++)
|
|
{
|
|
effectOverrides[i].ApplyChangesToMaterial(mat);
|
|
}
|
|
|
|
for (int i = 0; i < generalPropertiesOverrides.Count; i++)
|
|
{
|
|
generalPropertiesOverrides[i].ApplyChangesToMaterial(mat);
|
|
}
|
|
}
|
|
|
|
private void CollectAffectedMaterialsOnCurrentScene(List<Material> affectedMaterials)
|
|
{
|
|
for (int i = 0; i < rendererOverrides.Length; i++)
|
|
{
|
|
affectedMaterials.AddRange(rendererOverrides[i].sourceMaterials);
|
|
}
|
|
}
|
|
|
|
private void CollectAffectedMaterialsOnSelectedFolders(List<Material> affectedMaterials)
|
|
{
|
|
HashSet<string> materialsInFolderGUIDs = new HashSet<string>();
|
|
|
|
for (int i = 0; i < folders.Length; i++)
|
|
{
|
|
string folderPath = AssetDatabase.GetAssetPath(folders[i]);
|
|
if (AssetDatabase.IsValidFolder(folderPath))
|
|
{
|
|
string[] assetsPathsInFolder = AssetDatabase.FindAssets("t: Material", new string[] { folderPath });
|
|
|
|
for (int j = 0; j < assetsPathsInFolder.Length; j++)
|
|
{
|
|
materialsInFolderGUIDs.Add(assetsPathsInFolder[j]);
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach (string guid in materialsInFolderGUIDs)
|
|
{
|
|
string path = AssetDatabase.GUIDToAssetPath(guid);
|
|
Material mat = AssetDatabase.LoadAssetAtPath<Material>(path);
|
|
|
|
if (EditorUtils.IsAllIn13DShader(mat.shader))
|
|
{
|
|
affectedMaterials.Add(mat);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void CollectAffectedMaterialsAllProject(List<Material> affectedMaterials)
|
|
{
|
|
string[] materialsGUIDs = AssetDatabase.FindAssets("t: Material");
|
|
|
|
foreach (string guid in materialsGUIDs)
|
|
{
|
|
string path = AssetDatabase.GUIDToAssetPath(guid);
|
|
Material mat = AssetDatabase.LoadAssetAtPath<Material>(path);
|
|
|
|
if (EditorUtils.IsAllIn13DShader(mat.shader))
|
|
{
|
|
affectedMaterials.Add(mat);
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool IsApplyEnabled()
|
|
{
|
|
bool res = false;
|
|
|
|
switch (applyTarget)
|
|
{
|
|
case ApplyTarget.SELECTED_FOLDERS:
|
|
res = (folders != null) && (folders.Length > 0);
|
|
break;
|
|
case ApplyTarget.CURRENT_SCENE:
|
|
res = true;
|
|
break;
|
|
case ApplyTarget.ALL_PROJECT:
|
|
res = true;
|
|
break;
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
public AbstractEffectOverride AddEffectOverride(AllIn13DEffectConfig effectConfig)
|
|
{
|
|
AbstractEffectOverride res = FindEffectOverride(effectConfig.keywordPropertyName);
|
|
|
|
if (res == null)
|
|
{
|
|
switch (effectConfig.effectConfigType)
|
|
{
|
|
case EffectConfigType.EFFECT_ENUM:
|
|
res = new EffectEnumOverride(effectConfig);
|
|
break;
|
|
case EffectConfigType.EFFECT_TOGGLE:
|
|
res = new EffectToggleOverride(effectConfig);
|
|
break;
|
|
}
|
|
|
|
effectOverrides.Add(res);
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
public void AddCopmleteEffectOverride(AllIn13DEffectConfig effectConfig, Shader shader)
|
|
{
|
|
AbstractEffectOverride effectOverride = FindEffectOverride(effectConfig.keywordPropertyName);
|
|
|
|
if(effectOverride == null)
|
|
{
|
|
effectOverride = AddEffectOverride(effectConfig);
|
|
}
|
|
|
|
for (int i = 0; i < effectConfig.effectProperties.Count; i++)
|
|
{
|
|
effectOverride.AddPropertyOverride(effectConfig.effectProperties[i], shader);
|
|
}
|
|
}
|
|
|
|
public void AddPropertyOverride(AllIn13DEffectConfig effectConfig, EffectProperty effectProperty, Shader shader)
|
|
{
|
|
AbstractEffectOverride effectOverride = FindEffectOverride(effectConfig.keywordPropertyName);
|
|
|
|
effectOverride = AddEffectOverride(effectConfig);
|
|
effectOverride.AddPropertyOverride(effectProperty.propertyIndex, shader);
|
|
}
|
|
|
|
public void AddGeneralPropertyOverride(int propertyIndex, Shader shader)
|
|
{
|
|
PropertyOverride propertyOverride = new PropertyOverride(null, propertyIndex, shader);
|
|
if (!generalPropertiesOverrides.Contains(propertyOverride))
|
|
{
|
|
generalPropertiesOverrides.Add(propertyOverride);
|
|
}
|
|
}
|
|
|
|
public void RemoveEffectOverride(AbstractEffectOverride effectOverrideToRemove)
|
|
{
|
|
effectOverrides.Remove(effectOverrideToRemove);
|
|
|
|
RebuildPreviewMaterial();
|
|
}
|
|
|
|
public void RemovePropertyOverride(PropertyOverride propertyOverride)
|
|
{
|
|
bool removeSuccessfully = propertyOverride.Remove();
|
|
if (!removeSuccessfully)
|
|
{
|
|
generalPropertiesOverrides.Remove(propertyOverride);
|
|
}
|
|
}
|
|
|
|
public void RebuildPreviewMaterial()
|
|
{
|
|
for (int i = 0; i < rendererOverrides.Length; i++)
|
|
{
|
|
rendererOverrides[i].CleanPreviewMaterials();
|
|
}
|
|
|
|
ShowPreviewChanges();
|
|
}
|
|
|
|
public void ShowPreviewChanges()
|
|
{
|
|
for (int i = 0; i < rendererOverrides.Length; i++)
|
|
{
|
|
RendererOverride rendererOverride = rendererOverrides[i];
|
|
|
|
rendererOverride.UsePreviewMaterials();
|
|
|
|
ApplyChangesToMaterials(rendererOverride.previewMaterials);
|
|
}
|
|
}
|
|
|
|
public AbstractEffectOverride FindEffectOverride(string effectPropertyName)
|
|
{
|
|
AbstractEffectOverride res = null;
|
|
|
|
for(int i = 0; i < effectOverrides.Count; i++)
|
|
{
|
|
if (effectOverrides[i].propertyName == effectPropertyName)
|
|
{
|
|
res = effectOverrides[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
public bool IsEmpty()
|
|
{
|
|
bool res = effectOverrides.Count <= 0 && generalPropertiesOverrides.Count <= 0;
|
|
return res;
|
|
}
|
|
|
|
public bool DiscardChanges(Renderer[] renderers)
|
|
{
|
|
bool changes = false;
|
|
|
|
for(int i = this.rendererOverrides.Length - 1; i >= 0; i--)
|
|
{
|
|
for(int j = 0; j < renderers.Length; j++)
|
|
{
|
|
if (this.rendererOverrides[i].renderer == renderers[j])
|
|
{
|
|
rendererOverrides[i].DiscardChanges();
|
|
ArrayUtility.RemoveAt(ref this.rendererOverrides, i);
|
|
|
|
changes = true;
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return changes;
|
|
}
|
|
}
|
|
} |