-
-
Notifications
You must be signed in to change notification settings - Fork 821
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow `UIEffect` component to automatically select shaders like 'UIEffect-SoftMaskable' without any manual configuration. close #270
- Loading branch information
Showing
25 changed files
with
593 additions
and
164 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
158 changes: 158 additions & 0 deletions
158
Packages/src/Runtime/Internal/Utilities/ShaderSampleImporter.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
#if UNITY_EDITOR | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using UnityEngine; | ||
using System.Linq; | ||
using UnityEditor; | ||
using UnityEditor.PackageManager.UI; | ||
using PackageInfo = UnityEditor.PackageManager.PackageInfo; | ||
|
||
namespace Coffee.UIEffectInternal | ||
{ | ||
internal static class ShaderSampleImporter | ||
{ | ||
private static (string shaderName, string sampleName, string version)[] s_Samples; | ||
private static (string guid, string fileName)[] s_DeprecatedShaders; | ||
private static readonly Dictionary<string, string> s_SampleNames = new Dictionary<string, string>(); | ||
|
||
public static void RegisterShaderSamples((string shaderName, string sampleName, string version)[] samples) | ||
{ | ||
if (IsBatchOrBuilding()) return; | ||
|
||
// Collect sample names. | ||
s_Samples = samples; | ||
foreach (var (shaderName, sampleName, _) in samples) | ||
{ | ||
s_SampleNames[shaderName] = sampleName; | ||
} | ||
} | ||
|
||
public static void RegisterDeprecatedShaders((string, string)[] deprecatedShaders) | ||
{ | ||
if (IsBatchOrBuilding()) return; | ||
|
||
s_DeprecatedShaders = deprecatedShaders; | ||
} | ||
|
||
/// <summary> | ||
/// Import the sample containing the requested shader. | ||
/// If choice 'Import' is selected, the sample is imported. | ||
/// If choice 'Skip in this session' is selected, the sample is skipped in this session. | ||
/// </summary> | ||
public static bool ImportShaderIfSelected(string shaderName) | ||
{ | ||
if (IsBatchOrBuilding()) return false; | ||
|
||
// Find sample name. | ||
if (s_SampleNames.TryGetValue(shaderName, out var sampleName)) | ||
{ | ||
var message = $"Import the sample '{sampleName}' to use the shader '{shaderName}'."; | ||
return ImportSampleIfSelected(sampleName, message); | ||
} | ||
|
||
return false; | ||
} | ||
|
||
private static bool ImportSampleIfSelected(string sampleName, string message) | ||
{ | ||
if (IsBatchOrBuilding()) return false; | ||
if (!s_SampleNames.ContainsValue(sampleName)) return false; | ||
|
||
// Find package info. | ||
var pInfo = PackageInfo.FindForAssembly(typeof(ShaderSampleImporter).Assembly); | ||
if (pInfo == null) return false; | ||
|
||
// Find sample. If not found (resolvedPath == null), skip. | ||
var sample = Sample.FindByPackage(pInfo.name, pInfo.version) | ||
.FirstOrDefault(x => x.displayName == sampleName); | ||
if (sample.resolvedPath == null) return false; | ||
|
||
// Import the sample if selected. | ||
if (!string.IsNullOrEmpty(message)) | ||
{ | ||
var selected = EditorUtility.DisplayDialog($"Import {sampleName}", message, "Import", "Cancel"); | ||
if (!selected) return false; | ||
} | ||
|
||
// Remove the imported sample name from the list. | ||
foreach (var shaderName in s_SampleNames.Keys.ToArray()) | ||
{ | ||
if (s_SampleNames[shaderName] != sampleName) continue; | ||
s_SampleNames.Remove(shaderName); | ||
DeleteShader(shaderName); | ||
} | ||
|
||
// Import the sample in the next frame. | ||
EditorApplication.delayCall += () => sample.Import(Sample.ImportOptions.OverridePreviousImports); | ||
return true; | ||
} | ||
|
||
private static string GetVersion(string shaderName) | ||
{ | ||
if (string.IsNullOrEmpty(shaderName)) return null; | ||
|
||
var shader = Shader.Find(shaderName); | ||
if (!shader) return null; | ||
|
||
var path = AssetDatabase.GetAssetPath(shader); | ||
if (string.IsNullOrEmpty(path)) return null; | ||
|
||
return AssetImporter.GetAtPath(path).userData; | ||
} | ||
|
||
private static void DeleteShader(string shaderName) | ||
{ | ||
var shader = Shader.Find(shaderName); | ||
if (shader) | ||
{ | ||
AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(shader)); | ||
} | ||
} | ||
|
||
private static bool IsBatchOrBuilding() | ||
{ | ||
return Application.isBatchMode || BuildPipeline.isBuildingPlayer; | ||
} | ||
|
||
public static void Update() | ||
{ | ||
if (s_Samples == null || IsBatchOrBuilding()) return; | ||
|
||
// Find package info. | ||
var pInfo = PackageInfo.FindForAssembly(typeof(ShaderSampleImporter).Assembly); | ||
if (pInfo == null) return; | ||
|
||
// Find sample. If not found (resolvedPath == null), skip. | ||
var sample = Sample.FindByPackage(pInfo.name, pInfo.version).FirstOrDefault(); | ||
if (sample.resolvedPath == null) return; | ||
|
||
// Update the sample. | ||
foreach (var (shaderName, sampleName, version) in s_Samples) | ||
{ | ||
if (string.IsNullOrEmpty(version)) continue; | ||
if (!s_SampleNames.ContainsValue(sampleName)) continue; | ||
|
||
// If the shader exist and the version is different, add the sample to the update list. | ||
var currentVersion = GetVersion(shaderName); | ||
if (currentVersion != null && currentVersion != version && ImportSampleIfSelected(sampleName, null)) | ||
{ | ||
Debug.Log($"Updating '{sampleName}' to use the package '{pInfo.displayName} v{pInfo.version}'."); | ||
} | ||
} | ||
|
||
// Remove deprecated shaders. | ||
foreach (var (guid, fileName) in s_DeprecatedShaders) | ||
{ | ||
var path = AssetDatabase.GUIDToAssetPath(guid); | ||
if (!string.IsNullOrEmpty(path) && Path.GetFileName(path) == fileName) | ||
{ | ||
AssetDatabase.DeleteAsset(path); | ||
} | ||
} | ||
|
||
s_Samples = null; | ||
} | ||
} | ||
} | ||
#endif |
11 changes: 11 additions & 0 deletions
11
Packages/src/Runtime/Internal/Utilities/ShaderSampleImporter.cs.meta
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Oops, something went wrong.