Skip to content

Commit

Permalink
feat: add project settings for SoftMask
Browse files Browse the repository at this point in the history
  • Loading branch information
mob-sakai committed Feb 11, 2024
1 parent c451cf5 commit 4a124d4
Show file tree
Hide file tree
Showing 7 changed files with 272 additions and 0 deletions.
21 changes: 21 additions & 0 deletions Assets/ProjectSettings/UISoftMask.asset
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: eb5b5e33068c14a2bacdd6575e94f505, type: 3}
m_Name: UISoftMask
m_EditorClassIdentifier:
m_SoftMaskEnabled: 1
m_StereoEnabled: 0
m_FallbackBehavior: 0
m_TransformSensitivity: 0
m_EnabledInEditMode: 1
m_AutoIncludeShaders: 1
m_StripShaderVariants: 1
8 changes: 8 additions & 0 deletions Assets/ProjectSettings/UISoftMask.asset.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

55 changes: 55 additions & 0 deletions Packages/src/Editor/UISoftMaskProjectSettingsEditor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using Coffee.UISoftMask.Internal;
using UnityEditor;
using UnityEngine;

namespace Coffee.UISoftMask
{
[CustomEditor(typeof(UISoftMaskProjectSettings))]
internal class UISoftMaskProjectSettingsEditor : Editor
{
private static readonly GUIContent s_ContentUpgrade = new GUIContent("Upgrade");
private static readonly GUIContent s_ContentUpgradeButton = new GUIContent("Upgrade All Assets For V2");

public override void OnInspectorGUI()
{
var prevEnabled = UISoftMaskProjectSettings.softMaskEnabled;
base.OnInspectorGUI();
if (prevEnabled != UISoftMaskProjectSettings.softMaskEnabled)
{
UISoftMaskProjectSettings.ResetAllSoftMasks();
}

// Draw SoftMask/SoftMaskable/TerminalShape Shaders;
EditorGUILayout.BeginHorizontal();
{
EditorGUILayout.PrefixLabel("Included Shaders");
if (GUILayout.Button("Reset", EditorStyles.miniButton, GUILayout.Width(80)))
{
UISoftMaskProjectSettings.instance.ReloadShaders(true);
}
}
EditorGUILayout.EndHorizontal();

foreach (var shader in AlwaysIncludedShadersProxy.GetShaders())
{
if (!UISoftMaskProjectSettings.CanIncludeShader(shader)) continue;

EditorGUILayout.BeginHorizontal();
EditorGUILayout.ObjectField(shader, typeof(Shader), false);
if (GUILayout.Button("-", EditorStyles.miniButton, GUILayout.Width(20)))
{
AlwaysIncludedShadersProxy.Remove(shader);
}

EditorGUILayout.EndHorizontal();
}

EditorGUILayout.Space();
EditorGUILayout.LabelField(s_ContentUpgrade, EditorStyles.boldLabel);
if (GUILayout.Button(s_ContentUpgradeButton))
{
EditorApplication.delayCall += () => new UISoftMaskModifierRunner().RunIfUserWantsTo();
}
}
}
}
12 changes: 12 additions & 0 deletions Packages/src/Editor/UISoftMaskProjectSettingsEditor.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Packages/src/Runtime/ProjectSettings.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

157 changes: 157 additions & 0 deletions Packages/src/Runtime/ProjectSettings/UISoftMaskProjectSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
#pragma warning disable CS0414
using System.Linq;
using Coffee.UISoftMask.Internal;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;
#if UNITY_MODULE_VR
using UnityEngine.XR;
#endif

namespace Coffee.UISoftMask
{
public class UISoftMaskProjectSettings : PreloadedProjectSettings<UISoftMaskProjectSettings>
{
public enum FallbackBehavior
{
DefaultSoftMaskable,
None
}

public enum TransformSensitivity
{
Low,
Medium,
High
}

private static bool s_UseStereoMock;

[Header("Setting")]
[SerializeField]
internal bool m_SoftMaskEnabled = true;

[SerializeField]
private bool m_StereoEnabled = true;

[SerializeField]
private FallbackBehavior m_FallbackBehavior;

[SerializeField]
private TransformSensitivity m_TransformSensitivity = TransformSensitivity.Medium;

[Header("Editor")]
[SerializeField]
private bool m_EnabledInEditMode = true;

[Header("Shader")]
[SerializeField]
private bool m_AutoIncludeShaders = true;

[SerializeField]
internal bool m_StripShaderVariants = true;

public static bool softMaskEnabled
{
get
{
#if UNITY_EDITOR
if (!Application.isPlaying && !instance.m_EnabledInEditMode) return false;
#endif
return instance.m_SoftMaskEnabled;
}
}

#if UNITY_MODULE_VR
public static bool stereoEnabled => softMaskEnabled && instance.m_StereoEnabled && XRSettings.enabled;
#else
public static bool stereoEnabled => false;
#endif

public static FallbackBehavior fallbackBehavior => instance.m_FallbackBehavior;

public static TransformSensitivity transformSensitivity
{
get => instance.m_TransformSensitivity;
set => instance.m_TransformSensitivity = value;
}

public static float sensitivity
{
get
{
switch (instance.m_TransformSensitivity)
{
case TransformSensitivity.Low: return 1f / (1 << 2);
case TransformSensitivity.Medium: return 1f / (1 << 5);
case TransformSensitivity.High: return 1f / (1 << 12);
default: return 1f / (1 << (int)instance.m_TransformSensitivity);
}
}
}

public static bool useStereoMock
{
get => s_UseStereoMock;
set
{
if (s_UseStereoMock == value) return;
s_UseStereoMock = value;
ResetAllSoftMasks();
}
}

internal static void ResetAllSoftMasks()
{
var softMasks = ListPool<SoftMask>.Rent();
var components = ListPool<IMaskable>.Rent();
foreach (var softMask in FindObjectsOfType<SoftMask>())
{
softMask.GetComponentsInParent(true, softMasks);
if (1 < softMasks.Count) continue;

softMask.GetComponentsInChildren(true, components);
components.ForEach(c => c.RecalculateMasking());
}

ListPool<IMaskable>.Return(ref components);
ListPool<SoftMask>.Return(ref softMasks);
}

#if UNITY_EDITOR
private void Reset()
{
ReloadShaders(false);
}

internal void ReloadShaders(bool force)
{
if (!force && !m_AutoIncludeShaders) return;

foreach (var shader in AssetDatabase.FindAssets("t:Shader")
.Select(AssetDatabase.GUIDToAssetPath)
.Select(AssetDatabase.LoadAssetAtPath<Shader>)
.Where(CanIncludeShader))
{
AlwaysIncludedShadersProxy.Add(shader);
}
}

internal static bool CanIncludeShader(Shader shader)
{
if (!shader) return false;

var name = shader.name;
return name.EndsWith(" (SoftMaskable)")
|| name == "Hidden/UI/SoftMask"
|| name == "Hidden/UI/TerminalMaskingShape";
}

[SettingsProvider]
private static SettingsProvider CreateSettingsProvider()
{
return new PreloadedProjectSettingsProvider("Project/UI/Soft Mask");
}
#endif
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 4a124d4

Please sign in to comment.