Upload project file

This commit is contained in:
Misaki
2024-08-15 17:00:11 +09:00
parent 684c51a8c0
commit e441bb7911
162 changed files with 63084 additions and 0 deletions

View File

@@ -0,0 +1,109 @@
//#define USE_GITHUB_DOC_LINK
#define USE_UTS_DOC_LINK
using System;
using System.Runtime.CompilerServices;
using System.Diagnostics;
using System.Linq;
using UnityEngine;
#if UNITY_EDITOR
using PackageInfo = UnityEditor.PackageManager.PackageInfo;
#endif
namespace UnityEditor.Rendering.Toon
{
#if UNITY_2021_1_OR_NEWER
/// <summary>
/// Attribute to define the help url
/// </summary>
/// <example>
/// [CoreRPHelpURLAttribute("Volume")]
/// public class Volume : MonoBehaviour
/// </example>
[Conditional("UNITY_EDITOR")]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Enum, AllowMultiple = false)]
internal class UTS3InspectorHelpURLAttribute : HelpURLAttribute
{
/// <summary>
/// The constructor of the attribute
/// </summary>
/// <param name="pageName"></param>
/// <param name="packageName"></param>
internal UTS3InspectorHelpURLAttribute(string pageName, string packageName = "com.unity.toonshader")
: base(UTS3DocumentationInfo.GetPageLink(packageName, pageName))
{
}
}
//We need to have only one version number amongst packages (so public)
/// <summary>
/// Documentation Info class.
/// </summary>
internal class UTS3DocumentationInfo
{
internal const string fallbackVersion = "0.7";
#if USE_GITHUB_DOC_LINK
const string fallbackVersion = "";
const string url = "https://github.com/Unity-Technologies/{0}/blob/development/v1/{0}/Documentation~/";
#elif USE_UTS_DOC_LINK
const string url = "https://docs.unity3d.com/Packages/{0}@{1}/manual/";
#else
const string url = "https://docs.unity3d.com/Packages/{0}@{1}/manual/{2}.html";
#endif
/// <summary>
/// Current version of the documentation.
/// </summary>
internal static string version
{
get
{
return fallbackVersion;
}
}
/// <summary>
/// Generates a help url for the given package and page name
/// </summary>
/// <param name="packageName">The package name</param>
/// <param name="pageName">The page name</param>
/// <returns>The full url page</returns>
internal static string GetPageLink(string packageName, string pageName) => string.Format(url, packageName, version, pageName);
}
/// <summary>
/// Set of utils for documentation
/// </summary>
internal static class UTS3DocumentationUtils
{
/// <summary>
/// Obtains the help url from an enum
/// </summary>
/// <typeparam name="TEnum">The enum with a <see cref="HelpURLAttribute"/></typeparam>
/// <param name="mask">[Optional] The current value of the enum</param>
/// <returns>The full url</returns>
internal static string GetHelpURL<TEnum>(TEnum mask = default)
where TEnum : struct, IConvertible
{
var type = mask.GetType();
var attribute = type.GetCustomAttributes(typeof(HelpURLAttribute), false);
var helpURLAttribute = (HelpURLAttribute)mask
.GetType()
.GetCustomAttributes(typeof(HelpURLAttribute), false)
.FirstOrDefault();
#if USE_GITHUB_DOC_LINK
return helpURLAttribute == null ? string.Empty : $"{helpURLAttribute.URL}{mask}.md";
#elif USE_UTS_DOC_LINK
return helpURLAttribute == null ? string.Empty : $"{helpURLAttribute.URL}{mask}.html";
#else
return helpURLAttribute == null ? string.Empty : $"{helpURLAttribute.URL}#{mask}";
#endif
}
}
#endif // #if UNITY_2021_1_OR_NEWER
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 97edfa0389f572d4eb382422a0da4214
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,238 @@
using UnityEngine;
namespace UnityEditor.Rendering
{
/// <summary>
/// Set of extensions to allow storing, getting and setting the expandable states of a <see cref="MaterialEditor"/> areas
/// </summary>
public static partial class UTS3MaterialEditorExtension
{
const string k_KeyPrefix = "CoreRP:Material:UI_State:";
/// <summary>
/// Obtains if an area is expanded in a <see cref="MaterialEditor"/>
/// </summary>
/// <param name="editor"><see cref="MaterialEditor"/></param>
/// <param name="mask">The mask identifying the area to check the state</param>
/// <param name="defaultExpandedState">Default value if is key is not present</param>
/// <returns>true if the area is expanded</returns>
internal static bool IsAreaExpanded(this MaterialEditor editor, uint mask, uint defaultExpandedState = uint.MaxValue)
{
string key = editor.GetEditorPrefsKey();
if (EditorPrefs.HasKey(key))
{
uint state = (uint)EditorPrefs.GetInt(key);
return (state & mask) > 0;
}
EditorPrefs.SetInt(key, (int)defaultExpandedState);
return (defaultExpandedState & mask) > 0;
}
/// <summary>
/// Sets if the area is expanded <see cref="MaterialEditor"/>
/// </summary>
/// <param name="editor"><see cref="MaterialEditor"/></param>
/// <param name="mask">The mask identifying the area to check the state</param>
internal static void SetIsAreaExpanded(this MaterialEditor editor, uint mask, bool value)
{
string key = editor.GetEditorPrefsKey();
uint state = (uint)EditorPrefs.GetInt(key);
if (value)
{
state |= mask;
}
else
{
mask = ~mask;
state &= mask;
}
EditorPrefs.SetInt(key, (int)state);
}
static string GetEditorPrefsKey(this MaterialEditor editor)
{
return k_KeyPrefix + (editor.target as Material).shader.name;
}
}
/// <summary>
/// Set of extensions to handle more shader property drawer
/// </summary>
public static partial class MaterialEditorExtension
{
static Rect GetRect(MaterialProperty prop)
{
return EditorGUILayout.GetControlRect(true, MaterialEditor.GetDefaultPropertyHeight(prop), EditorStyles.layerMaskField);
}
/// <summary>
/// Draw an integer property field for a float shader property.
/// </summary>
/// <param name="editor"><see cref="MaterialEditor"/></param>
/// <param name="prop">The MaterialProperty to make a field for</param>
/// <param name="label">Label for the property</param>
/// <param name="transform">Optional function to apply on the new value</param>
public static void IntShaderProperty(this MaterialEditor editor, MaterialProperty prop, GUIContent label, System.Func<int, int> transform = null)
{
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = prop.hasMixedValue;
int newValue = EditorGUI.IntField(GetRect(prop), label, (int)prop.floatValue);
EditorGUI.showMixedValue = false;
if (EditorGUI.EndChangeCheck())
{
if (transform != null)
newValue = transform(newValue);
prop.floatValue = newValue;
}
}
/// <summary>
/// Draw an integer slider for a range shader property.
/// </summary>
/// <param name="editor"><see cref="MaterialEditor"/></param>
/// <param name="prop">The MaterialProperty to make a field for</param>
/// <param name="label">Label for the property</param>
public static void IntSliderShaderProperty(this MaterialEditor editor, MaterialProperty prop, GUIContent label)
{
var limits = prop.rangeLimits;
editor.IntSliderShaderPropertyUTS3(prop, (int)limits.x, (int)limits.y, label);
}
/// <summary>
/// Draw an integer slider for a float shader property.
/// </summary>
/// <param name="editor"><see cref="MaterialEditor"/></param>
/// <param name="prop">The MaterialProperty to make a field for</param>
/// <param name="min">The value at the left end of the slider</param>
/// <param name="max">The value at the right end of the slider</param>
/// <param name="label">Label for the property</param>
public static void IntSliderShaderPropertyUTS3(this MaterialEditor editor, MaterialProperty prop, int min, int max, GUIContent label)
{
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = prop.hasMixedValue;
int newValue = EditorGUI.IntSlider(GetRect(prop), label, (int)prop.floatValue, min, max);
EditorGUI.showMixedValue = false;
if (EditorGUI.EndChangeCheck())
{
editor.RegisterPropertyChangeUndo(label.text);
prop.floatValue = newValue;
}
}
/// <summary>
/// Draw a property field for a float shader property.
/// </summary>
/// <param name="editor"><see cref="MaterialEditor"/></param>
/// <param name="prop">The MaterialProperty to make a field for</param>
/// <param name="label">Label for the property</param>
/// <param name="min">The minimum value the user can specify</param>
public static void MinFloatShaderProperty(this MaterialEditor editor, MaterialProperty prop, GUIContent label, float min)
{
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = prop.hasMixedValue;
float newValue = EditorGUI.FloatField(GetRect(prop), label, prop.floatValue);
newValue = Mathf.Max(min, newValue);
EditorGUI.showMixedValue = false;
if (EditorGUI.EndChangeCheck())
prop.floatValue = newValue;
}
/// <summary>
/// Draw a popup selection field for a float shader property.
/// </summary>
/// <param name="editor"><see cref="MaterialEditor"/></param>
/// <param name="prop">The MaterialProperty to make a field for</param>
/// <param name="label">Label for the property</param>
/// <param name="displayedOptions">An array with the options shown in the popup</param>
/// <returns>The index of the option that has been selected by the user</returns>
public static int PopupShaderProperty(this MaterialEditor editor, MaterialProperty prop, GUIContent label, string[] displayedOptions)
{
int val = (int)prop.floatValue;
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = prop.hasMixedValue;
int newValue = EditorGUILayout.Popup(label, val, displayedOptions);
EditorGUI.showMixedValue = false;
if (EditorGUI.EndChangeCheck() && (newValue != val || prop.hasMixedValue))
{
editor.RegisterPropertyChangeUndo(label.text);
prop.floatValue = val = newValue;
}
return val;
}
/// <summary>
/// Draw an integer popup selection field for a float shader property.
/// </summary>
/// <param name="editor"><see cref="MaterialEditor"/></param>
/// <param name="prop">The MaterialProperty to make a field for</param>
/// <param name="label">Label for the property</param>
/// <param name="displayedOptions">An array with the options shown in the popup</param>
/// <param name="optionValues">An array with the values for each option</param>
/// <returns>The value of the option that has been selected by the user</returns>
public static int IntPopupShaderProperty(this MaterialEditor editor, MaterialProperty prop, string label, string[] displayedOptions, int[] optionValues)
{
int val = (int)prop.floatValue;
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = prop.hasMixedValue;
int newValue = EditorGUILayout.IntPopup(label, val, displayedOptions, optionValues);
EditorGUI.showMixedValue = false;
if (EditorGUI.EndChangeCheck() && (newValue != val || prop.hasMixedValue))
{
editor.RegisterPropertyChangeUndo(label);
prop.floatValue = val = newValue;
}
return val;
}
/// <summary>
/// Draw a special slider to specify a range between a min and a max for two float shader properties.
/// </summary>
/// <param name="editor"><see cref="MaterialEditor"/></param>
/// <param name="min">The MaterialProperty containing the lower value of the range the slider shows</param>
/// <param name="max">The MaterialProperty containing the upper value of the range the slider shows</param>
/// <param name="minLimit">The limit at the left end of the slider</param>
/// <param name="maxLimit">The limit at the right end of the slider</param>
/// <param name="label">Label for the property</param>
public static void MinMaxShaderProperty(MaterialProperty min, MaterialProperty max, float minLimit, float maxLimit, GUIContent label)
{
float minValue = min.floatValue;
float maxValue = max.floatValue;
EditorGUI.BeginChangeCheck();
EditorGUILayout.MinMaxSlider(label, ref minValue, ref maxValue, minLimit, maxLimit);
if (EditorGUI.EndChangeCheck())
{
min.floatValue = minValue;
max.floatValue = maxValue;
}
}
/// <summary>
/// Draw a special slider to specify a range between a min and a max for a vector shader property.
/// </summary>
/// <param name="editor"><see cref="MaterialEditor"/></param>
/// <param name="remapProp">The MaterialProperty containing the range the slider shows in the x and y components of its vectorValue</param>
/// <param name="minLimit">The limit at the left end of the slider</param>
/// <param name="maxLimit">The limit at the right end of the slider</param>
/// <param name="label">Label for the property</param>
public static void MinMaxShaderProperty(this MaterialEditor editor, MaterialProperty remapProp, float minLimit, float maxLimit, GUIContent label)
{
Vector2 remap = remapProp.vectorValue;
EditorGUI.BeginChangeCheck();
EditorGUILayout.MinMaxSlider(label, ref remap.x, ref remap.y, minLimit, maxLimit);
if (EditorGUI.EndChangeCheck())
remapProp.vectorValue = remap;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 432c07d3f1a19184e937060c4277a185
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,151 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Rendering;
namespace UnityEditor.Rendering.Toon
{
/// <summary>
/// Create a toggleable header for material UI, must be used within a scope.
/// <example>Example:
/// <code>
/// void OnGUI()
/// {
/// using (var header = new MaterialHeaderScope(text, ExpandBit, editor))
/// {
/// if (header.expanded)
/// EditorGUILayout.LabelField("Hello World !");
/// }
/// }
/// </code>
/// </example>
/// </summary>
public struct UTS3MaterialHeaderScope : IDisposable
{
/// <summary>Indicates whether the header is expanded or not. Is true if the header is expanded, false otherwise.</summary>
public readonly bool expanded;
bool spaceAtEnd;
#if !UNITY_2020_1_OR_NEWER
int oldIndentLevel;
#endif
internal static void DrawSplitter(bool isBoxed = false)
{
var rect = GUILayoutUtility.GetRect(1f, 1f);
float xMin = rect.xMin;
// Splitter rect should be full-width
rect.xMin = 0f;
rect.width += 4f;
if (isBoxed)
{
rect.xMin = xMin == 7.0 ? 4.0f : EditorGUIUtility.singleLineHeight;
rect.width -= 1;
}
if (Event.current.type != EventType.Repaint)
return;
EditorGUI.DrawRect(rect, !EditorGUIUtility.isProSkin
? new Color(0.6f, 0.6f, 0.6f, 1.333f)
: new Color(0.12f, 0.12f, 0.12f, 1.333f));
}
/// <summary> Draw a foldout header </summary>
/// <param name="title"> The title of the header </param>
/// <param name="state"> The state of the header </param>
/// <returns>return the state of the foldout header</returns>
internal static bool DrawHeaderFoldout(GUIContent title, bool state, bool isBoxed = false, Func<bool> hasMoreOptions = null, Action toggleMoreOptions = null, string documentationURL = "", Action<Vector2> contextAction = null)
{
#if SRPCORE_NEWERTHAN12_IS_INSTALLED_FOR_UTS
return CoreEditorUtils.DrawHeaderFoldout(title, state, documentationURL: documentationURL);
#else
return EditorGUILayout.Foldout(state, title);
#endif
}
internal static bool DrawSubHeaderFoldout(GUIContent title, bool state, bool isBoxed = false)
{
#if SRPCORE_NEWERTHAN12_IS_INSTALLED_FOR_UTS
return CoreEditorUtils.DrawSubHeaderFoldout(title, state, isBoxed: false);
#else
return EditorGUILayout.Foldout(state, title);
#endif
}
/// <summary>
/// Creates a material header scope to display the foldout in the material UI.
/// </summary>
/// <param name="title">GUI Content of the header.</param>
/// <param name="bitExpanded">Bit index which specifies the state of the header (whether it is open or collapsed) inside Editor Prefs.</param>
/// <param name="materialEditor">The current material editor.</param>
/// <param name="spaceAtEnd">Set this to true to make the block include space at the bottom of its UI. Set to false to not include any space.</param>
/// <param name="subHeader">Set to true to make this into a sub-header. This affects the style of the header. Set to false to make this use the standard style.</param>
/// <param name="defaultExpandedState">The default state if the header is not present</param>
/// <param name="documentationURL">[optional] Documentation page</param>
public UTS3MaterialHeaderScope(GUIContent title, uint bitExpanded, MaterialEditor materialEditor, bool spaceAtEnd = true, bool subHeader = false, uint defaultExpandedState = uint.MaxValue, string documentationURL = "")
{
if (title == null)
throw new ArgumentNullException(nameof(title));
bool beforeExpanded = materialEditor.IsAreaExpanded(bitExpanded, defaultExpandedState);
#if !UNITY_2020_1_OR_NEWER
oldIndentLevel = EditorGUI.indentLevel;
EditorGUI.indentLevel = subHeader ? 1 : 0; //fix for preset in 2019.3 (preset are one more indentation depth in material)
#endif
this.spaceAtEnd = spaceAtEnd;
if (!subHeader)
DrawSplitter();
GUILayout.BeginVertical();
bool saveChangeState = GUI.changed;
expanded = subHeader
? DrawSubHeaderFoldout(title, beforeExpanded, isBoxed: false)
: DrawHeaderFoldout(title, beforeExpanded, documentationURL: documentationURL);
if (expanded ^ beforeExpanded)
{
materialEditor.SetIsAreaExpanded((uint)bitExpanded, expanded);
saveChangeState = true;
}
GUI.changed = saveChangeState;
if (expanded)
++EditorGUI.indentLevel;
}
/// <summary>
/// Creates a material header scope to display the foldout in the material UI.
/// </summary>
/// <param name="title">Title of the header.</param>
/// <param name="bitExpanded">Bit index which specifies the state of the header (whether it is open or collapsed) inside Editor Prefs.</param>
/// <param name="materialEditor">The current material editor.</param>
/// <param name="spaceAtEnd">Set this to true to make the block include space at the bottom of its UI. Set to false to not include any space.</param>
/// <param name="subHeader">Set to true to make this into a sub-header. This affects the style of the header. Set to false to make this use the standard style.</param>
public UTS3MaterialHeaderScope(string title, uint bitExpanded, MaterialEditor materialEditor, bool spaceAtEnd = true, bool subHeader = false)
: this(EditorGUIUtility.TrTextContent(title, string.Empty), bitExpanded, materialEditor, spaceAtEnd, subHeader)
{
}
/// <summary>Disposes of the material scope header and cleans up any resources it used.</summary>
void IDisposable.Dispose()
{
if (expanded)
{
if (spaceAtEnd && (Event.current.type == EventType.Repaint || Event.current.type == EventType.Layout))
EditorGUILayout.Space();
--EditorGUI.indentLevel;
}
#if !UNITY_2020_1_OR_NEWER
EditorGUI.indentLevel = oldIndentLevel;
#endif
GUILayout.EndVertical();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9cb5a8fc48f6bd54d8c2f1bed2469f74
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,29 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Rendering;
namespace UnityEditor.Rendering.Toon
{
internal struct UTS3MaterialHeaderScopeItem
{
/// <summary><see cref="GUIContent"></see> that will be rendered on the <see cref="MaterialHeaderScope"></see></summary>
public GUIContent headerTitle { get; set; }
/// <summary>The bitmask for this scope</summary>
public uint expandable { get; set; }
/// <summary>The action that will draw the controls for this scope</summary>
public Action<Material> drawMaterialScope { get; set; }
/// <summary>The url of the scope</summary>
public string url { get; set; }
/// <summary>The mode of UTS rendering mode</summary>
public uint workflowMode { get; set; }
/// <summary>The flag wheter UTS material is in transparent mode</summary>
public uint transparentEnabled { get; set; }
/// <summary>The flag wheter UTS material is in tessellation mode</summary>
public uint tessellationEnabled { get; set; }
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d54c94fe8f4745240a693f3b99c54d6c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,84 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace UnityEditor.Rendering.Toon
{
/// <summary>
/// Collection to store <see cref="UTS3MaterialHeaderScopeItem"></see>
/// </summary>
public class UTS3MaterialHeaderScopeList
{
internal readonly uint m_DefaultExpandedState;
internal readonly List<UTS3MaterialHeaderScopeItem> m_Items = new List<UTS3MaterialHeaderScopeItem>();
/// <summary>
/// Constructor that initializes it with the default expanded state for the internal scopes
/// </summary>
/// <param name="defaultExpandedState">By default, everything is expanded</param>
public UTS3MaterialHeaderScopeList(uint defaultExpandedState = uint.MaxValue)
{
m_DefaultExpandedState = defaultExpandedState;
}
/// <summary>
/// Registers a <see cref="MaterialHeaderScopeItem"/> into the list
/// </summary>
/// <param name="title"><see cref="GUIContent"/> The title of the scope</param>
/// <param name="expandable">The mask identifying the scope</param>
/// <param name="action">The action that will be drawn if the scope is expanded</param>
/// <param name="workflowMode">UTS workflow mode </param> ///
/// <param name="isTransparent">Flag transparent material header should be drawn</param> ///
/// <param name="isTessellation">Flag Tessellation material header should be drawn</param> ///
public void RegisterHeaderScope<TEnum>(GUIContent title, TEnum expandable, Action<Material> action, uint isTransparent, uint isTessellation)
where TEnum : struct, IConvertible
{
m_Items.Add(new UTS3MaterialHeaderScopeItem()
{
headerTitle = title,
expandable = Convert.ToUInt32(expandable),
drawMaterialScope = action,
#if UNITY_2021_1_OR_NEWER
url = UTS3DocumentationUtils.GetHelpURL<TEnum>(expandable),
#else
url = string.Empty,
#endif
transparentEnabled = isTransparent,
tessellationEnabled = isTessellation
});
}
/// <summary>
/// Draws all the <see cref="MaterialHeaderScopeItem"/> with its information stored
/// </summary>
/// <param name="materialEditor"><see cref="MaterialEditor"/></param>
/// <param name="material"><see cref="Material"/></param>
public void DrawHeaders(MaterialEditor materialEditor, Material material)
{
if (material == null)
throw new ArgumentNullException(nameof(material));
if (materialEditor == null)
throw new ArgumentNullException(nameof(materialEditor));
foreach (UTS3MaterialHeaderScopeItem item in m_Items)
{
using (UTS3MaterialHeaderScope header = new UTS3MaterialHeaderScope(
item.headerTitle,
item.expandable,
materialEditor,
defaultExpandedState: m_DefaultExpandedState,
documentationURL: item.url))
{
if (!header.expanded)
continue;
EditorGUILayout.Space();
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 263acad4f2e9f8845acc91ad9bd040d2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: