摄像机区域的架构改动

This commit is contained in:
2026-05-15 14:47:24 +08:00
parent 1b37297585
commit f264329751
3591 changed files with 1687228 additions and 446503 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ead5874dc0cc5ad4589d728bff69696c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,257 @@
#if UNITY_EDITOR
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEditor;
namespace SpriteShadersUltimate
{
public class CodingHelper : EditorWindow
{
public GUIContent labelContent;
public MaterialProperty prop;
public static CodingHelper lastWindow;
bool isImage;
void OnGUI()
{
//Close:
if(labelContent == null || prop == null)
{
Close();
return;
}
EditorGUILayout.BeginVertical();
//Style:
GUIStyle labelStyle = new GUIStyle(GUI.skin.label);
labelStyle.richText = true;
//Internal Name:
GUI.color = new Color(1, 1, 1, 0.7f);
EditorGUILayout.LabelField("<b><size=14>Property Name:</size></b>", labelStyle);
GUI.color = Color.white;
DisplayCode("<b>" + prop.name + "</b>", labelStyle);
EditorGUILayout.Space(); EditorGUILayout.Space();
EditorGUILayout.Space(); EditorGUILayout.Space();
EditorGUILayout.Space(); EditorGUILayout.Space();
//Code:
GUI.color = new Color(1, 1, 1, 0.7f);
EditorGUILayout.LabelField("<b><size=14>Set Function:</size></b>", labelStyle);
GUI.color = Color.white;
string codeText = default;
string propertyText = default;
if (prop.type == MaterialProperty.PropType.Color)
{
propertyText = "public Color colorValue;";
codeText = "material.SetColor(<b>\"" + prop.name + "\"</b>, colorValue);";
}
else if (prop.type == MaterialProperty.PropType.Vector)
{
propertyText = "public Vector2 vectorValue;";
codeText = "material.SetVector(<b>\"" + prop.name + "\"</b>, vectorValue);";
}
else if (prop.type == MaterialProperty.PropType.Texture)
{
propertyText = "public Texture textureValue;";
codeText = "material.SetTexture(<b>\"" + prop.name + "\"</b>, textureValue);";
}
else
{
propertyText = "public float floatValue;";
codeText = "material.SetFloat(<b>\"" + prop.name + "\"</b>, floatValue);";
}
DisplayCode(codeText, labelStyle);
//Example:
EditorGUILayout.Space(); EditorGUILayout.Space();
EditorGUILayout.Space(); EditorGUILayout.Space();
EditorGUILayout.Space(); EditorGUILayout.Space();
GUI.color = new Color(1, 1, 1, 0.7f);
EditorGUILayout.LabelField("<b><size=14>Example Code:</size></b>", labelStyle);
GUI.color = Color.white;
Rect lastRect = GUILayoutUtility.GetLastRect();
lastRect.x += lastRect.width - 160;
lastRect.width = 100;
if (!isImage)
{
GUI.enabled = false;
}
if (GUI.Button(lastRect, "Sprite Renderer"))
{
isImage = false;
GUI.FocusControl(null);
Repaint();
}
if(isImage)
{
GUI.enabled = false;
}
else
{
GUI.enabled = true;
}
lastRect.x += 100;
lastRect.width = 60;
if (GUI.Button(lastRect, "UI Image"))
{
isImage = true;
GUI.FocusControl(null);
Repaint();
}
GUI.enabled = true;
string[] lines = codeText.Split('\n');
codeText = "";
for(int n = 0; n < lines.Length; n++)
{
codeText += " " + lines[n] + ((n < lines.Length - 1) ? "\n" : "");
}
string exampleText = default;
if(isImage)
{
exampleText = @"using UnityEngine;
using UnityEngine.UI;
public class Example : MonoBehaviour
{
" + propertyText + @"
Material material;
void Start()
{
Image image = GetComponent<Image>();
image.material = Instantiate(image.material);
material = image.materialForRendering;
}
void Update()
{
" + codeText + @"
}
}";
}
else
{
exampleText = @"using UnityEngine;
public class Example : MonoBehaviour
{
" + propertyText + @"
Material material;
void Start()
{
SpriteRenderer spriteRenderer = GetComponent<SpriteRenderer>();
material = spriteRenderer.material;
}
void Update()
{
" + codeText + @"
}
}";
}
DisplayCode(exampleText, labelStyle);
//Final:
EditorGUILayout.Space(); EditorGUILayout.Space();
EditorGUILayout.Space(); EditorGUILayout.Space();
EditorGUILayout.Space(); EditorGUILayout.Space();
GUI.color = new Color(1, 1, 1, 0.7f);
EditorGUILayout.LabelField("Do you need <b>more</b> help ?", labelStyle);
EditorGUILayout.LabelField("Check out the <b>documentation</b> or <b>contact</b> me.", labelStyle);
GUI.color = Color.white;
EditorGUILayout.Space();
SSUShaderGUI.DisplaySupportInformation();
EditorGUILayout.EndVertical();
Rect contentRect = GUILayoutUtility.GetLastRect();
if(Mathf.Abs(position.height - contentRect.height - 50) > 5 && contentRect.height > 400)
{
Rect newPosition = new Rect(position);
newPosition.height = contentRect.height + 50;
position = newPosition;
}
Rect closeRect = new Rect(position);
closeRect.width = 60;
closeRect.height = 30;
closeRect.x = position.width - 70;
closeRect.y = position.height - 40;
GUIStyle buttonStyle = new GUIStyle(GUI.skin.button);
buttonStyle.richText = true;
if(GUI.Button(closeRect, "<size=16>Close</size>", buttonStyle))
{
Close();
}
}
void DisplayCode(string codeText, GUIStyle labelStyle)
{
EditorGUILayout.BeginVertical("Helpbox");
int lines = codeText.Split('\n').Length;
EditorGUILayout.SelectableLabel(codeText, labelStyle, GUILayout.Height(lines * 16));
EditorGUILayout.EndVertical();
Rect lastRect = GUILayoutUtility.GetLastRect();
lastRect.x += lastRect.width - 115;
lastRect.width = 115;
lastRect.y += lastRect.height - 1;
lastRect.height = 20;
if (GUI.Button(lastRect, "Copy to Clipboard"))
{
EditorGUIUtility.systemCopyBuffer = codeText.Replace("<b>","").Replace("</b>","");
}
}
public static void Open(GUIContent labelContent, MaterialProperty prop, Shader shader, float width)
{
if(lastWindow != null)
{
lastWindow.Close();
lastWindow = null;
}
CodingHelper window = CreateInstance(typeof(CodingHelper)) as CodingHelper;
window.ShowUtility();
window.labelContent = labelContent;
window.prop = prop;
window.titleContent = new GUIContent("Coding Hints - " + labelContent.text);
window.isImage = (Selection.activeGameObject != null && Selection.activeGameObject.GetComponent<Graphic>() != null) || shader.name.Contains("UI");
Vector2 position = new Vector2(window.position.x, window.position.y);
if(Event.current != null)
{
position = GUIUtility.GUIToScreenPoint(Event.current.mousePosition);
position.x -= 500 + width;
position.y -= 300;
}
window.position = new Rect(position.x, position.y, 500, 665);
lastWindow = window;
}
}
}
#endif

View File

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

View File

@@ -0,0 +1,106 @@
#if UNITY_EDITOR
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEditor;
namespace SpriteShadersUltimate
{
[CustomEditor(typeof(ImageSSU))]
[CanEditMultipleObjects]
public class ImageSSUEditor : Editor
{
public override void OnInspectorGUI()
{
SerializedProperty updateChanges = serializedObject.FindProperty("updateChanges");
EditorGUILayout.PropertyField(updateChanges);
GUI.enabled = false;
EditorGUILayout.PropertyField(serializedObject.FindProperty("runtimeMaterial"));
GUI.enabled = true;
serializedObject.ApplyModifiedProperties();
GUIStyle labelStyle = new GUIStyle(GUI.skin.label);
labelStyle.richText = true;
EditorGUILayout.Space();
EditorGUILayout.BeginVertical("Helpbox");
GUI.color = new Color(1, 1, 1, 0.7f);
EditorGUILayout.LabelField("Requires the <b>UI_Graphic</b> shader space.", labelStyle);
EditorGUILayout.LabelField("Sets the material's <b>Rect Width</b> and <b>Rect Height</b>.", labelStyle);
EditorGUILayout.LabelField("Will also <b>instantiate</b> the material at runtime.", labelStyle);
GUI.color = Color.white;
EditorGUILayout.EndVertical();
//Check:
ImageSSU image = (ImageSSU) target;
if(image.GetComponent<RectTransform>() == null)
{
EditorGUILayout.Space();
GUI.color = Color.red;
EditorGUILayout.BeginVertical("Helpbox");
EditorGUILayout.LabelField("Requires a <b>RectTransform</b>.", labelStyle);
EditorGUILayout.EndVertical();
GUI.color = Color.white;
}
if (image.GetComponent<Image>() == null)
{
EditorGUILayout.Space();
GUI.color = Color.red;
EditorGUILayout.BeginVertical("Helpbox");
EditorGUILayout.LabelField("Requires an <b>Image</b>.", labelStyle);
EditorGUILayout.EndVertical();
GUI.color = Color.white;
}
else if(Application.isPlaying == false)
{
Material mat = image.GetComponent<Image>().material;
if (mat.shader.name.StartsWith("Sprite Shaders Ultimate") == false)
{
EditorGUILayout.Space();
GUI.color = Color.red;
EditorGUILayout.BeginVertical("Helpbox");
EditorGUILayout.LabelField("Requires a <b>Sprite Shaders Ultimate</b> shader.", labelStyle);
EditorGUILayout.EndVertical();
GUI.color = Color.white;
}
else if (Mathf.RoundToInt(mat.GetFloat("_ShaderSpace")) != 5)
{
EditorGUILayout.Space();
GUI.color = Color.red;
EditorGUILayout.BeginVertical("Helpbox");
EditorGUILayout.LabelField("Requires <b>UI_Graphic</b> shader space.", labelStyle);
EditorGUILayout.EndVertical();
GUI.color = Color.white;
}
else
{
EditorGUILayout.Space();
GUI.color = Color.green;
EditorGUILayout.BeginVertical("Helpbox");
if (updateChanges.hasMultipleDifferentValues)
{
EditorGUILayout.LabelField("<b>Rect Width</b> and <b>Rect Height</b> will be updated on <b>Awake()</b> or <b>Update()</b>.", labelStyle);
}
else if (updateChanges.boolValue)
{
EditorGUILayout.LabelField("<b>Rect Width</b> and <b>Rect Height</b> will be updated on <b>Awake()</b> and <b>Update()</b>.", labelStyle);
EditorGUILayout.LabelField("Material is only updated if the RectTransform's <b>Width</b> or <b>Height</b> is <b>changed</b>.", labelStyle);
}
else
{
EditorGUILayout.LabelField("<b>Rect Width</b> and <b>Rect Height</b> will be updated on <b>Awake()</b>.", labelStyle);
}
EditorGUILayout.EndVertical();
GUI.color = Color.white;
}
}
}
}
}
#endif

View File

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

View File

@@ -0,0 +1,59 @@
#if UNITY_EDITOR
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEditor;
namespace SpriteShadersUltimate
{
[CustomEditor(typeof(MaterialInstancerSSU))]
[CanEditMultipleObjects]
public class MaterialInstancerSSUEditor : Editor
{
public override void OnInspectorGUI()
{
GUIStyle labelStyle = new GUIStyle(GUI.skin.label);
labelStyle.richText = true;
GUI.enabled = false;
EditorGUILayout.PropertyField(serializedObject.FindProperty("runtimeMaterial"));
GUI.enabled = true;
EditorGUILayout.Space();
EditorGUILayout.BeginVertical("Helpbox");
GUI.color = new Color(1, 1, 1, 0.7f);
EditorGUILayout.LabelField("Will <b>instantiate</b> materials at runtime.", labelStyle);
EditorGUILayout.LabelField("Fixes shaders requiring a <b>unique material instance</b>.", labelStyle);
GUI.color = Color.white;
EditorGUILayout.EndVertical();
//Check:
MaterialInstancerSSU materialInstancer = (MaterialInstancerSSU)target;
if(materialInstancer.GetComponent<Renderer>() == null && materialInstancer.GetComponent<Graphic>() == null)
{
EditorGUILayout.Space();
GUI.color = Color.red;
EditorGUILayout.BeginVertical("Helpbox");
EditorGUILayout.LabelField("Requires a <b>UI Graphic</b> or <b>Renderer</b> with a material.", labelStyle);
EditorGUILayout.EndVertical();
GUI.color = Color.white;
}
else
{
EditorGUILayout.Space();
GUI.color = Color.green;
EditorGUILayout.BeginVertical("Helpbox");
EditorGUILayout.LabelField("<b>Material</b> will be instanced on <b>Awake()</b>.", labelStyle);
EditorGUILayout.EndVertical();
GUI.color = Color.white;
}
}
}
}
#endif

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -0,0 +1,451 @@
#if UNITY_EDITOR
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEngine.UI;
using UnityEngine.Rendering;
namespace SpriteShadersUltimate
{
[CustomEditor(typeof(ShaderFaderSSU))]
[CanEditMultipleObjects]
public class ShaderFaderSSUEditor : Editor
{
List<string> shaderProperties;
float previewValue;
public override void OnInspectorGUI()
{
GUIStyle labelStyle = new GUIStyle(GUI.skin.label);
labelStyle.richText = true;
EditorGUI.BeginChangeCheck();
serializedObject.UpdateIfRequiredOrScript();
EditorGUILayout.BeginVertical();
SerializedProperty property = serializedObject.GetIterator();
bool expanded = true;
bool displayObjectLists = true;
bool automaticFading = true;
while (property.NextVisible(expanded))
{
using (new EditorGUI.DisabledScope("m_Script" == property.propertyPath))
{
bool draw = true;
//Hide fade value.
if (property.name == "fadeValue")
{
//GUI.enabled = false;
}
//Hide object lists.
if (property.name == "getChildObjects")
{
displayObjectLists = property.boolValue;
}
else if ((property.name == "renderers" || property.name == "graphics") && displayObjectLists)
{
draw = false;
}
//Hide fading variables.
if (property.name == "automaticFading")
{
automaticFading = property.boolValue;
}
else if ((property.name == "isFaded" || property.name == "duration" || property.name == "unscaledTime") && !automaticFading)
{
draw = false;
}
else if ((property.name == "fadeValue") && automaticFading)
{
draw = false;
}
//Create box groups.
if (property.name == "getChildObjects" || property.name == "automaticFading" || property.name == "floatProperties")
{
EditorGUILayout.EndVertical();
EditorGUILayout.Space();
EditorGUILayout.BeginVertical("Helpbox");
}
//Fix box arrow overlap.
if (property.hasVisibleChildren)
{
EditorGUI.indentLevel += 1;
}
//DRAW PROPERTY:
if (draw)
{
if (property.name == "automaticFading")
{
int selected = property.boolValue ? 0 : 1;
selected = GUILayout.Toolbar(selected, new string[] { "Automatic Fading", "Manual Fading" });
property.boolValue = selected == 0 ? true : false;
}
else if (property.name == "getChildObjects")
{
int selected = property.boolValue ? 0 : 1;
selected = GUILayout.Toolbar(selected, new string[] { "Get From Children", "Manual Objects" });
property.boolValue = selected == 0 ? true : false;
}
else
{
EditorGUILayout.PropertyField(property, true);
}
}
//Fix box arrow overlap.
if (property.hasVisibleChildren)
{
EditorGUI.indentLevel -= 1;
}
//Reset stuff.
GUI.enabled = true;
expanded = false;
}
}
EditorGUILayout.EndVertical();
serializedObject.ApplyModifiedProperties();
EditorGUI.EndChangeCheck();
//Utility:
EditorGUILayout.Space();
EditorGUILayout.BeginVertical("Helpbox");
EditorGUILayout.BeginHorizontal();
#region Utility Buttons
if (GUILayout.Button("Copy From"))
{
ShaderFaderSSU sf = (ShaderFaderSSU)target;
foreach (Material mat in GetMaterials())
{
Shader shader = mat.shader;
for(int i = 0; i < shader.GetPropertyCount(); i++)
{
ShaderPropertyType propertyType = shader.GetPropertyType(i);
string propertyName = shader.GetPropertyName(i);
if (SSUShaderGUI.IsKeyword(propertyName) || propertyName.StartsWith("_Enable"))
{
continue;
}
if (propertyType == ShaderPropertyType.Float || propertyType == ShaderPropertyType.Range)
{
//Float:
float propertyValue = mat.GetFloat(propertyName);
bool foundProperty = false;
foreach (FloatFaderSSU propertyFader in sf.floatProperties)
{
if (propertyFader.propertyName == shader.GetPropertyName(i))
{
propertyFader.fromValue = propertyValue;
foundProperty = true;
break;
}
}
if (!foundProperty)
{
sf.floatProperties.Add(new FloatFaderSSU(propertyName, propertyValue, propertyValue));
}
}
else if (propertyType == ShaderPropertyType.Vector)
{
//Vector:
Vector4 propertyValue = mat.GetVector(propertyName);
bool foundProperty = false;
foreach (VectorFaderSSU propertyFader in sf.vectorProperties)
{
if (propertyFader.propertyName == shader.GetPropertyName(i))
{
propertyFader.fromValue = propertyValue;
foundProperty = true;
break;
}
}
if (!foundProperty)
{
sf.vectorProperties.Add(new VectorFaderSSU(propertyName, propertyValue, propertyValue));
}
}
else if (propertyType == ShaderPropertyType.Color)
{
//Color:
Color propertyValue = mat.GetColor(propertyName);
bool foundProperty = false;
foreach (ColorFaderSSU propertyFader in sf.colorProperties)
{
if (propertyFader.propertyName == shader.GetPropertyName(i))
{
propertyFader.fromValue = propertyValue;
foundProperty = true;
break;
}
}
if (!foundProperty)
{
sf.colorProperties.Add(new ColorFaderSSU(propertyName, propertyValue, propertyValue));
}
}
}
}
}
if (GUILayout.Button("Copy To"))
{
ShaderFaderSSU sf = (ShaderFaderSSU)target;
foreach (Material mat in GetMaterials())
{
Shader shader = mat.shader;
for (int i = 0; i < shader.GetPropertyCount(); i++)
{
ShaderPropertyType propertyType = shader.GetPropertyType(i);
string propertyName = shader.GetPropertyName(i);
if (SSUShaderGUI.IsKeyword(propertyName) || propertyName.StartsWith("_Enable"))
{
continue;
}
if (propertyType == ShaderPropertyType.Float || propertyType == ShaderPropertyType.Range)
{
//Float:
float propertyValue = mat.GetFloat(propertyName);
bool foundProperty = false;
foreach (FloatFaderSSU propertyFader in sf.floatProperties)
{
if (propertyFader.propertyName == shader.GetPropertyName(i))
{
propertyFader.toValue = propertyValue;
foundProperty = true;
break;
}
}
if (!foundProperty)
{
sf.floatProperties.Add(new FloatFaderSSU(propertyName, propertyValue, propertyValue));
}
}
else if (propertyType == ShaderPropertyType.Vector)
{
//Vector:
Vector4 propertyValue = mat.GetVector(propertyName);
bool foundProperty = false;
foreach (VectorFaderSSU propertyFader in sf.vectorProperties)
{
if (propertyFader.propertyName == shader.GetPropertyName(i))
{
propertyFader.toValue = propertyValue;
foundProperty = true;
break;
}
}
if (!foundProperty)
{
sf.vectorProperties.Add(new VectorFaderSSU(propertyName, propertyValue, propertyValue));
}
}
else if (propertyType == ShaderPropertyType.Color)
{
//Color:
Color propertyValue = mat.GetColor(propertyName);
bool foundProperty = false;
foreach (ColorFaderSSU propertyFader in sf.colorProperties)
{
if (propertyFader.propertyName == shader.GetPropertyName(i))
{
propertyFader.toValue = propertyValue;
foundProperty = true;
break;
}
}
if (!foundProperty)
{
sf.colorProperties.Add(new ColorFaderSSU(propertyName, propertyValue, propertyValue));
}
}
}
}
}
if (GUILayout.Button("Cleanup"))
{
ShaderFaderSSU sf = (ShaderFaderSSU)target;
//Float:
List<FloatFaderSSU> removedFloatProperties = new List<FloatFaderSSU>();
foreach (FloatFaderSSU propertyFader in sf.floatProperties)
{
if(propertyFader.fromValue == propertyFader.toValue)
{
removedFloatProperties.Add(propertyFader);
}
}
foreach (FloatFaderSSU propertyFader in removedFloatProperties)
{
sf.floatProperties.Remove(propertyFader);
}
//Vector:
List<VectorFaderSSU> removedVectorProperties = new List<VectorFaderSSU>();
foreach (VectorFaderSSU propertyFader in sf.vectorProperties)
{
if (propertyFader.fromValue == propertyFader.toValue)
{
removedVectorProperties.Add(propertyFader);
}
}
foreach (VectorFaderSSU propertyFader in removedVectorProperties)
{
sf.vectorProperties.Remove(propertyFader);
}
//Color:
List<ColorFaderSSU> removedColorProperties = new List<ColorFaderSSU>();
foreach (ColorFaderSSU propertyFader in sf.colorProperties)
{
if (propertyFader.fromValue == propertyFader.toValue)
{
removedColorProperties.Add(propertyFader);
}
}
foreach (ColorFaderSSU propertyFader in removedColorProperties)
{
sf.colorProperties.Remove(propertyFader);
}
}
#endregion
EditorGUILayout.EndHorizontal();
#region Preview
float lastPreview = previewValue;
previewValue = EditorGUILayout.Slider(new GUIContent("Preview", "This will modify the materials."), previewValue, 0, 1);
if (previewValue != lastPreview)
{
ShaderFaderSSU sf = (ShaderFaderSSU)target;
float fadeFactor = sf.fadeCurve.Evaluate(previewValue);
foreach (Material mat in GetMaterials())
{
sf.UpdateSingleMaterial(mat, fadeFactor);
}
}
#endregion
EditorGUILayout.EndVertical();
EditorGUILayout.Space();
EditorGUILayout.BeginVertical("Helpbox");
GUI.color = new Color(1, 1, 1, 0.7f);
EditorGUILayout.LabelField("Fades material <b>properties</b> between two values.", labelStyle);
EditorGUILayout.LabelField("", labelStyle);
EditorGUILayout.LabelField("<b>Objects:</b>", labelStyle);
EditorGUILayout.LabelField("First <b>assign</b> the objects, whose <b>materials</b> should be faded.", labelStyle);
EditorGUILayout.LabelField("These can either be <b>children</b> of this gameobject or <b>manually</b> assigned.", labelStyle);
EditorGUILayout.LabelField("", labelStyle);
EditorGUILayout.LabelField("<b>Properties:</b>", labelStyle);
EditorGUILayout.LabelField("Next you need to add the material <b>properties</b>, which you want to fade.", labelStyle);
EditorGUILayout.LabelField("These can be <b>added</b> manually or <b>setup</b> using the <b>utility buttons</b>.", labelStyle);
EditorGUILayout.LabelField("Only <b>floats</b>, <b>colors</b> and <b>vectors</b> can be faded. Do no try to fade <b>toggles</b>.", labelStyle);
EditorGUILayout.LabelField("", labelStyle);
EditorGUILayout.LabelField("<b>Quick Setup:</b>", labelStyle);
EditorGUILayout.LabelField("First <b>modify</b> the materials to their <b>faded out</b> state and press <b>[Copy From]</b>.", labelStyle);
EditorGUILayout.LabelField("Then <b>modify</b> the materials to their <b>faded in</b> state and press <b>[Copy To]</b>.", labelStyle);
EditorGUILayout.LabelField("Finally press <b>[Cleanup]</b> to <b>remove</b> all <b>unmodified</b> properties.", labelStyle);
EditorGUILayout.LabelField("", labelStyle);
EditorGUILayout.LabelField("<b>Scripting:</b>", labelStyle);
EditorGUILayout.LabelField("For <b>automatic fading</b> simply toggle the <b>isFaded</b> boolean at runtime.", labelStyle);
EditorGUILayout.LabelField("For <b>manual fading</b> modify the <b>fadeValue</b> float at runtime.", labelStyle);
EditorGUILayout.LabelField("Materials are only <b>updated</b>, when the <b>fadeValue</b> changes.", labelStyle);
GUI.color = Color.white;
EditorGUILayout.EndVertical();
}
HashSet<Material> GetMaterials()
{
HashSet<Material> materials = new HashSet<Material>();
ShaderFaderSSU sf = (ShaderFaderSSU)target;
if (sf.getChildObjects)
{
//Auto Renderers:
foreach (Renderer renderer in sf.gameObject.GetComponentsInChildren<Renderer>(true))
{
if(!materials.Contains(renderer.sharedMaterial))
{
materials.Add(renderer.sharedMaterial);
}
}
//Auto Graphics:
foreach (Graphic graphic in sf.gameObject.GetComponentsInChildren<Graphic>(true))
{
if (!materials.Contains(graphic.material))
{
materials.Add(graphic.material);
}
}
}
else
{
//Manual Renderers:
if (sf.renderers != null)
{
foreach (Renderer renderer in sf.renderers)
{
if (renderer != null)
{
if (!materials.Contains(renderer.sharedMaterial))
{
materials.Add(renderer.sharedMaterial);
}
}
}
}
//Manual Graphics:
if (sf.graphics != null)
{
foreach (Graphic graphic in sf.graphics)
{
if (graphic != null)
{
if (!materials.Contains(graphic.material))
{
materials.Add(graphic.material);
}
}
}
}
}
return materials;
}
}
}
#endif

View File

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

View File

@@ -0,0 +1,41 @@
#if UNITY_EDITOR
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace SpriteShadersUltimate
{
[CreateAssetMenu(fileName = "ShaderName", menuName = "Shader/SSU Shader Hint (ignore this)")]
public class ShaderHintSSU : ScriptableObject
{
[Header("Main:")]
[TextArea(6, 10)]
public string shaderDescription;
public List<HintText> hints = new List<HintText>();
public List<string> lines = new List<string>();
public string spaceHint = "";
[Header("Extra Help:")]
public bool requiresFullRectMesh = false;
public bool requiresSpriteSheetFix = false;
public bool requiresInstancing = false;
public bool requiresTiling = false;
[Header("Performance:")]
public float benchmarkValue = 0f;
public int textureSamples = 0;
public string textureToggle = "";
public string textureToggleExtra = "";
}
[System.Serializable]
public class HintText
{
public string property = "";
public string text = "";
}
}
#endif

View File

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

View File

@@ -0,0 +1,50 @@
#if UNITY_EDITOR
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEditor;
namespace SpriteShadersUltimate
{
[CustomEditor(typeof(SpriteSheetSSU))]
[CanEditMultipleObjects]
public class SpriteSheetSSUEditor : Editor
{
public override void OnInspectorGUI()
{
SerializedProperty updateChanges = serializedObject.FindProperty("updateChanges");
EditorGUILayout.PropertyField(updateChanges);
serializedObject.ApplyModifiedProperties();
GUIStyle labelStyle = new GUIStyle(GUI.skin.label);
labelStyle.richText = true;
EditorGUILayout.Space();
EditorGUILayout.BeginVertical("Helpbox");
GUI.color = new Color(1, 1, 1, 0.7f);
EditorGUILayout.LabelField("Only supports <b>images</b> and <b>sprite renderers</b>.", labelStyle);
EditorGUILayout.LabelField("Requires the <b>Sprite Sheet Fix</b> option enabled.", labelStyle);
EditorGUILayout.LabelField("Sets the material's <b>Sprite Sheet Rect</b> to fix shader issues.", labelStyle);
EditorGUILayout.LabelField("Will also <b>instantiate</b> materials at runtime.", labelStyle);
GUI.color = Color.white;
EditorGUILayout.EndVertical();
//Check:
SpriteSheetSSU targetComponent = (SpriteSheetSSU) target;
if(targetComponent.GetComponent<Image>() == null && targetComponent.GetComponent<SpriteRenderer>() == null)
{
EditorGUILayout.Space();
GUI.color = Color.red;
EditorGUILayout.BeginVertical("Helpbox");
EditorGUILayout.LabelField("Requires a <b>Sprite Renderer</b> or <b>Image</b> component.", labelStyle);
EditorGUILayout.EndVertical();
GUI.color = Color.white;
}
}
}
}
#endif

View File

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

View File

@@ -0,0 +1,48 @@
#if UNITY_EDITOR
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace SpriteShadersUltimate
{
[CustomEditor(typeof(UnscaledTimeSSU))]
[CanEditMultipleObjects]
public class UnscaledTimeSSUEditor : Editor
{
public override void OnInspectorGUI()
{
//Properties:
EditorGUILayout.PropertyField(serializedObject.FindProperty("dontDestroyOnLoad"));
serializedObject.ApplyModifiedProperties();
EditorGUILayout.Space();
//Additional Information:
GUIStyle labelStyle = new GUIStyle(GUI.skin.label);
labelStyle.richText = true;
EditorGUILayout.BeginVertical("Helpbox");
GUI.color = new Color(1, 1, 1, 0.7f);
EditorGUILayout.LabelField("Allows you to use <b>unscaled time</b> in SSU shaders.", labelStyle);
EditorGUILayout.LabelField("Attach this to <b>any</b> gameobject.", labelStyle);
EditorGUILayout.LabelField("You only need <b>one</b> of this component in your scene.", labelStyle);
GUI.color = Color.white;
EditorGUILayout.EndVertical();
EditorGUILayout.Space();
GUI.color = Color.green;
EditorGUILayout.BeginVertical("Helpbox");
EditorGUILayout.LabelField("<b>Unscaled Time</b> can be used.", labelStyle);
if(serializedObject.FindProperty("dontDestroyOnLoad").boolValue)
{
EditorGUILayout.LabelField("This gameobject will <b>not</b> be <b>destroyed</b> when the scene <b>changes</b>.", labelStyle);
}
EditorGUILayout.EndVertical();
GUI.color = Color.white;
}
}
}
#endif

View File

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

View File

@@ -0,0 +1,63 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace SpriteShadersUltimate
{
public class ImageSSU : InstancerSSU
{
//Updates material when RectTransform changes.
[Tooltip("Enable this if the size of the RectTransform will change.")]
public bool updateChanges = false;
//References:
RectTransform rectTransform;
//Property IDs:
int rectWidthID;
int rectHeightID;
//Previous SizeDelta:
Vector2 lastSizeDelta;
void Awake()
{
//Get RectTransform:
rectTransform = GetComponent<RectTransform>();
//Instantiate Material:
Image image = GetComponent<Image>();
image.material = Instantiate(image.material);
runtimeMaterial = image.materialForRendering;
//Shader IDs:
rectWidthID = Shader.PropertyToID("_RectWidth");
rectHeightID = Shader.PropertyToID("_RectHeight");
}
void Start()
{
//Set Values:
UpdateMaterial();
}
void Update()
{
if (updateChanges)
{
if (lastSizeDelta != rectTransform.sizeDelta)
{
UpdateMaterial();
}
}
}
public void UpdateMaterial()
{
lastSizeDelta = rectTransform.sizeDelta;
runtimeMaterial.SetFloat(rectWidthID, lastSizeDelta.x);
runtimeMaterial.SetFloat(rectHeightID, lastSizeDelta.y);
}
}
}

View File

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

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 47de9e558a270914fa68c4b48910445d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 71fb573462425de408507447a0bf2241
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,240 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace SpriteShadersUltimate
{
[CustomEditor(typeof(InteractiveWindSSU)), CanEditMultipleObjects]
public class InteractiveWindSSUEditor : Editor
{
bool displaySetup;
bool displayTroubleshooting;
bool displayInformation;
public override void OnInspectorGUI()
{
//References:
GUIStyle style = new GUIStyle(GUI.skin.label);
style.richText = true;
InteractiveWindSSU wind = (InteractiveWindSSU)target;
//Header:
EditorGUILayout.BeginVertical("Helpbox");
EditorGUILayout.LabelField("<size=14><b>Interactive Wind</b></size>", style);
EditorGUILayout.LabelField(" ", GUILayout.Height(1));
DisplayHints(ref displaySetup, "Setup",
"- Attach this to a <b>SpriteRenderer</b> with the <b>Wind</b> shader.",
"- Set <b>Mesh Type</b> to <b>Full Rect</b> in the sprite's settings.",
"- Attach a <b>BoxCollider2D</b> to this gameobject.",
"- Set <b>Is Trigger</b> to true in the <b>BoxCollider2D</b>.",
"- Have a single active <b>WindManager</b> component in your scene.",
" ",
"- You can <b>flip</b> the shader for hanging objects.",
"- You can combine the shader with <b>UV Distort</b>."
);
EditorGUILayout.LabelField(" ", GUILayout.Height(1));
DisplayHints(ref displayTroubleshooting, "Troubleshooting",
" ",
"<b>Pixels are clipping out:</b>",
"- Make sure the sprite's <b>Mesh Type</b> is <b>Full Rect</b>.",
"- <b>Sprite Sheets</b> need the <b>Sprite Sheet Fix</b> option.",
"- Expand the sprite's texture horizontally with empty pixels.",
" ",
"<b>Wind is not visible:</b>",
"- Make sure the SpriteRenderer is using the <b>Wind</b> shader.",
"- If using a <b>Uber Shader</b> you need to enable <b>Wind</b>.",
"- Make sure you have a single active <b>WindManager</b> component.",
"- Check your <b>WindManager's</b> and <b>material's</b> settings.",
" ",
"<b>Physical interaction is not happening:</b>",
"- Check this <b>component's</b> and the <b>material's</b> settings.",
"- Make sure the <b>BoxCollider2D</b> is positioned properly.",
"- Set the <b>BoxCollider2D</b> to a <b>trigger</b>.",
"- Make sure a collision with the <b>BoxCollider2D</b> is happening.",
" "
);
EditorGUILayout.LabelField(" ", GUILayout.Height(1));
DisplayHints(ref displayInformation, "Information",
" ",
"<b>Summary:</b>",
"- Interaction will <b>bend</b> and <b>squish</b> the sprite.",
"- Can be used for <b>Grass, Trees, Chains, Vines</b> and more.",
" ",
"<b>Temporary Interaction:</b>",
"- Disable <b>Stay Bent</b> to have a temporary interaction.",
"- Only objects moving faster than <b>" + Mathf.RoundToInt(wind.minBendSpeed) + " unit/s</b> will interact.",
" "
);
EditorGUILayout.EndVertical();
EditorGUILayout.Space();
//Rotation:
EditorGUILayout.BeginVertical("Helpbox");
EditorGUILayout.LabelField("<b>Rotation:</b>", style);
EditorGUILayout.PropertyField(serializedObject.FindProperty("rotationFactor"));
EditorGUILayout.PropertyField(serializedObject.FindProperty("bendInSpeed"));
EditorGUILayout.PropertyField(serializedObject.FindProperty("bendOutSpeed"));
EditorGUILayout.EndVertical();
EditorGUILayout.Space();
//Temporary:
EditorGUILayout.BeginVertical("Helpbox");
EditorGUILayout.LabelField("<b>Method:</b>", style);
EditorGUILayout.PropertyField(serializedObject.FindProperty("stayBent"));
if(!wind.stayBent)
{
EditorGUILayout.PropertyField(serializedObject.FindProperty("minBendSpeed"));
}
EditorGUILayout.EndVertical();
EditorGUILayout.Space();
//Hyper Performance:
EditorGUILayout.BeginVertical("Helpbox");
EditorGUILayout.LabelField("<b>Hyper Performance:</b>", style);
EditorGUILayout.PropertyField(serializedObject.FindProperty("hyperPerformanceMode"));
if (wind.hyperPerformanceMode)
{
EditorGUILayout.PropertyField(serializedObject.FindProperty("randomOffsetZ"));
EditorGUILayout.PropertyField(serializedObject.FindProperty("customMaterial"));
if (wind.customMaterial)
{
EditorGUILayout.PropertyField(serializedObject.FindProperty("inactiveMaterial"));
}
else
{
EditorGUILayout.PropertyField(serializedObject.FindProperty("inactiveShader"));
}
//Hint:
GUI.color = new Color(1, 1, 1, 0.7f);
EditorGUILayout.LabelField("- GPU performance boost for <b>lowest-end</b> mobile phones.", style);
if(!wind.customMaterial)
{
EditorGUILayout.LabelField("- Sets the shader to <b>" + wind.inactiveShader + "</b> while inactive.", style);
}
else
{
if(wind.inactiveMaterial != null)
{
EditorGUILayout.LabelField("- Sets the material to <b>" + wind.inactiveMaterial.name + "</b> while inactive.", style);
}
else
{
GUIStyle warningStyle = new GUIStyle(GUI.skin.label);
warningStyle.richText = true;
if (EditorGUIUtility.isProSkin)
{
warningStyle.normal.textColor = new Color(1, 0.7f, 0.7f, 1);
}
else
{
warningStyle.normal.textColor = new Color(0.3f, 0f, 0f, 1);
}
EditorGUILayout.LabelField("- Please reference a material in <b>Inactive Material</b>.", warningStyle);
}
}
EditorGUILayout.LabelField("- Use this if you want <b>physical interaction</b> but don't need <b>Wind</b>.", style);
EditorGUILayout.LabelField("- You must set <b>Rotation Wind Factor</b> to <b>0</b> in the material.", style);
EditorGUILayout.Space();
EditorGUILayout.LabelField("- Enabling <b>Random Offset Z</b> will prevent resorting of render order.", style);
GUI.color = Color.white;
}
EditorGUILayout.EndVertical();
EditorGUILayout.Space();
//Other:
EditorGUILayout.BeginVertical("Helpbox");
EditorGUILayout.LabelField("<b>Other:</b>", style);
EditorGUILayout.PropertyField(serializedObject.FindProperty("randomizeWiggle"));
EditorGUILayout.PropertyField(serializedObject.FindProperty("allowCustomLayer"));
EditorGUILayout.EndVertical();
serializedObject.ApplyModifiedProperties();
//Fix Layer:
if(wind.gameObject.layer != 2 && !wind.allowCustomLayer)
{
wind.gameObject.layer = 2;
}
//Fix BoxCollider2D:
BoxCollider2D boxCollider = wind.gameObject.GetComponent<BoxCollider2D>();
if(boxCollider == null)
{
//Create new BoxCollider2D:
boxCollider = wind.gameObject.AddComponent<BoxCollider2D>();
boxCollider.isTrigger = true;
}
//Fix Variables:
if(wind.bendInSpeed < 0)
{
wind.bendInSpeed = 0;
}
if (wind.bendOutSpeed < 0)
{
wind.bendOutSpeed = 0;
}
if (wind.minBendSpeed < 0)
{
wind.minBendSpeed = 0;
}
}
void DisplayHints(ref bool toggleVariable, string title,params string[] lines)
{
GUIStyle style = new GUIStyle(GUI.skin.label);
style.richText = true;
GUIStyle button = new GUIStyle(GUI.skin.button);
button.richText = true;
if (toggleVariable)
{
GUI.color = new Color(1, 1, 1, 0.7f);
}
else
{
GUI.color = new Color(1, 1, 1, 0.5f);
}
title = "<b>" + title + "</b>";
EditorGUILayout.BeginVertical(GUI.skin.box);
EditorGUILayout.BeginHorizontal();
GUI.color = Color.white;
EditorGUILayout.LabelField(title, style);
if (GUILayout.Button("<size=10>" + (toggleVariable ? "▼" : "▲") + "</size>", button, GUILayout.Width(20)))
{
toggleVariable = !toggleVariable;
}
EditorGUILayout.EndHorizontal();
if (toggleVariable == true)
{
GUI.color = new Color(1, 1, 1, 0.7f);
for(int l = 0; l < lines.Length; l++)
{
if(lines[l] == " ")
{
EditorGUILayout.LabelField(lines[l], style,GUILayout.Height(6));
}
else
{
EditorGUILayout.LabelField(lines[l], style);
}
}
}
GUI.color = Color.white;
EditorGUILayout.EndVertical();
}
}
}

View File

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

View File

@@ -0,0 +1,34 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace SpriteShadersUltimate
{
[CustomEditor(typeof(WindManagerSSU)), CanEditMultipleObjects]
public class WindManagerSSUEditor : Editor
{
public override void OnInspectorGUI()
{
//Draw Inspector:
base.OnInspectorGUI();
//References:
GUIStyle style = new GUIStyle(GUI.skin.label);
style.richText = true;
//Info Box:
EditorGUILayout.Space();
EditorGUILayout.BeginVertical("Helpbox");
EditorGUILayout.LabelField("<b><size=14>Information</size></b>", style);
GUI.color = new Color(1, 1, 1, 0.7f);
EditorGUILayout.LabelField("- This component will handle the global wind settings.", style);
EditorGUILayout.LabelField("- Only have one active <b>WindManager</b> at a time.", style);
EditorGUILayout.LabelField("- This updates the global variables used by my <b>wind shader</b>.", style);
GUI.color = new Color(1, 1, 1, 1f);
EditorGUILayout.EndVertical();
serializedObject.ApplyModifiedProperties();
}
}
}

View File

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

View File

@@ -0,0 +1,25 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace SpriteShadersUltimate
{
[CustomEditor(typeof(WindParallaxSSU))]
public class WindParallaxSSUEditor : Editor
{
public override void OnInspectorGUI()
{
GUIStyle style = new GUIStyle(GUI.skin.label);
style.richText = true;
EditorGUILayout.BeginVertical("Helpbox");
GUI.color = new Color(1, 1, 1, 0.7f);
EditorGUILayout.LabelField("Fixes <b>parallax</b> or <b>movement</b> issues for the <b>Wind</b> shader.", style);
EditorGUILayout.LabelField("Attach this to <b>sprite renderers</b> and enable <b>Is Parallax</b>.", style);
EditorGUILayout.LabelField("Set's <b>X Position</b> on <b>Awake()</b> to a static value.", style);
GUI.color = Color.white;
EditorGUILayout.EndVertical();
}
}
}

View File

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

View File

@@ -0,0 +1,64 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class InteractiveSquishSSU : MonoBehaviour
{
[Header("Settings:")]
public float squishSpeed = 5f;
public bool staySquished = true;
public float squishDuration = 0.1f;
//References:
Material mat;
//Internal:
float currentSquish;
float lastTriggerStayTime;
void Start()
{
mat = GetComponent<SpriteRenderer>().material;
currentSquish = 0f;
}
void OnTriggerStay2D(Collider2D collision)
{
if (staySquished)
{
lastTriggerStayTime = Time.time;
}
}
void OnTriggerEnter2D(Collider2D collision)
{
lastTriggerStayTime = Time.time;
}
void Update()
{
float newSquish = currentSquish;
if(Time.time > lastTriggerStayTime + squishDuration)
{
newSquish = Mathf.Lerp(newSquish, -0.1f, Time.deltaTime * squishSpeed);
}
else
{
newSquish = Mathf.Lerp(newSquish, 1.1f, Time.deltaTime * squishSpeed);
}
newSquish = Mathf.Clamp01(newSquish);
if(newSquish != currentSquish)
{
currentSquish = newSquish;
UpdateSquish();
}
}
void UpdateSquish()
{
mat.SetFloat("_SquishFade", currentSquish);
}
}

View File

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

View File

@@ -0,0 +1,254 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace SpriteShadersUltimate
{
public class InteractiveWindSSU : InstancerSSU
{
[Tooltip("How much physical interaction bends the sprite.")]
public float rotationFactor = 1.5f;
[Tooltip("How fast physical interaction bending fades in.")]
public float bendInSpeed = 8f;
[Tooltip("How fast physical interaction bending fades out.")]
public float bendOutSpeed = 8f;
[Tooltip("If disabled the sprite will only bend during active movement.")]
public bool stayBent = true;
[Tooltip("The minimum speed of the interacting object to trigger bending.")]
public float minBendSpeed = 1f;
[Tooltip("Swaps the material with the default sprite material while inactive.")]
public bool hyperPerformanceMode = false;
[Tooltip("Adds a tiny little offset to the Z position on start.\nTo prevent random resorting of render order.")]
public bool randomOffsetZ = true;
[Tooltip("Define a material to switch to while inactive.")]
public bool customMaterial = false;
[Tooltip("The shader used for the default sprite material.")]
public string inactiveShader = "Sprites/Default";
[Tooltip("The material used when inactive.")]
public Material inactiveMaterial;
[Tooltip("Slightly changes 'Wiggle Frequency', to desync the wiggle shaders of multiple sprites.")]
public bool randomizeWiggle = false;
[Tooltip("The editor-side script set's the layer to 'Ignore Raycast' to fix potential issues. Enable this to disable that and set the layer to a different one.")]
public bool allowCustomLayer = false;
//Variables:
HashSet<Collider2D> collidersInside;
BoxCollider2D boxCollider;
//Runtime:
float currentBending;
float currentRotationDirection;
bool isActive;
bool newDirection;
float lastPosition;
float lastBend;
float currentBendTarget;
bool bentInLastFrame;
SpriteRenderer sr;
static Material defaultMaterial;
int rotationId;
void Start()
{
//Initialize Variables:
collidersInside = new HashSet<Collider2D>();
boxCollider = GetComponent<BoxCollider2D>();
sr = GetComponent<SpriteRenderer>();
runtimeMaterial = sr.material;
if(defaultMaterial == null)
{
if (customMaterial)
{
defaultMaterial = inactiveMaterial;
}
else
{
defaultMaterial = new Material(Shader.Find(inactiveShader));
}
}
if(hyperPerformanceMode)
{
sr.material = defaultMaterial;
if(randomOffsetZ)
{
//Prevent Resorting:
Vector3 position = transform.position;
position.z += Random.value * 0.1f;
transform.position = position;
}
}
if(randomizeWiggle && runtimeMaterial != null)
{
float wiggleFrequency = runtimeMaterial.GetFloat("_WiggleFrequency") * (0.9f + 0.2f * Random.value);
runtimeMaterial.SetFloat("_WiggleFrequency", wiggleFrequency);
}
rotationId = Shader.PropertyToID("_WindRotation");
}
void FixedUpdate()
{
if (isActive == false) return;
Vector2 localPosition = new Vector2(0, -1000000);
foreach(Collider2D collider in collidersInside)
{
if(collider != null)
{
if(localPosition.y < -99999)
{
localPosition = collider.bounds.center - transform.position; //Collider Position
}
else
{
if (!newDirection) {
Vector2 newLocalPosition = (collider.bounds.center - transform.position);
if((currentRotationDirection < 0 && newLocalPosition.x > localPosition.x) || (currentRotationDirection > 0 && newLocalPosition.x < localPosition.x))
{
localPosition = newLocalPosition; //Take most heavy position
}
}
else
{
localPosition = ((Vector2)(collider.bounds.center - transform.position) + localPosition) * 0.5f; //Position Deviation (multiple colliders)
}
}
}
}
if (localPosition.y > -99999) //Colliders are interacting with the wind sprite.
{
//Bend Direction:
if (newDirection)
{
if(localPosition.x < 0)
{
currentRotationDirection = -1;
}else
{
currentRotationDirection = 1;
}
newDirection = false;
}
//Bend Target:
float targetBending = 0;
if(currentRotationDirection < 0)
{
targetBending = Mathf.Clamp01((localPosition.x + boxCollider.size.x * 0.5f) / boxCollider.size.x);
}
else
{
targetBending = Mathf.Clamp01((boxCollider.size.x * 0.5f - localPosition.x) / boxCollider.size.x);
}
if(stayBent)
{
//Staying Bend:
currentBendTarget = targetBending;
}
else
{
//Temporary Bend:
bool moved = Mathf.Abs(lastPosition - localPosition.x) > Time.fixedDeltaTime * minBendSpeed;
if(moved && lastBend != 0 && currentRotationDirection > 0 == (localPosition.x - lastPosition) > 0)
{
moved = false;
}
if (moved || bentInLastFrame)
{
currentBendTarget = targetBending;
lastBend = targetBending;
bentInLastFrame = true;
if (!moved)
{
bentInLastFrame = false;
}
}
else
{
currentBendTarget = Mathf.Lerp(currentBendTarget, 0, Time.fixedDeltaTime * bendInSpeed);
if (Mathf.Abs(currentBending) < 0.01f)
{
newDirection = true;
}
}
lastPosition = localPosition.x;
}
//Fade In Bending:
currentBending += (currentBendTarget * currentRotationDirection - currentBending) * Mathf.Min(bendInSpeed * Time.fixedDeltaTime, 1);
UpdateShader();
}
else
{
//Fade Out Bending:
currentBending -= currentBending * Mathf.Min(bendOutSpeed * Time.fixedDeltaTime,1);
UpdateShader();
if (Mathf.Abs(currentBending) < 0.005f)
{
isActive = false;
lastBend = 0;
if (hyperPerformanceMode)
{
sr.material = defaultMaterial;
}
}
}
}
public void UpdateShader()
{
runtimeMaterial.SetFloat(rotationId, -1f * currentBending * rotationFactor);
}
void OnTriggerEnter2D(Collider2D collision)
{
if(collidersInside.Count == 0 || Mathf.Abs(currentBending) < 0.2f)
{
newDirection = true;
}
collidersInside.Add(collision);
if (hyperPerformanceMode && isActive == false)
{
sr.material = runtimeMaterial;
}
isActive = true;
}
void OnTriggerExit2D(Collider2D collision)
{
if (collidersInside.Contains(collision))
{
collidersInside.Remove(collision);
}
}
//Other:
public static void DefaultCollider(BoxCollider2D box)
{
box.isTrigger = true;
box.size = new Vector2(2, 1);
box.offset = new Vector2(0, -0.5f);
}
}
}

View File

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

View File

@@ -0,0 +1,53 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace SpriteShadersUltimate
{
public class WindManagerSSU : MonoBehaviour
{
[Header("Settings:")]
[Tooltip("Smaller values will result in more frequent changes in wind.")]
public float windNoiseScale = 0.1f;
private float lastWindNoiseScale;
[Tooltip("Speed at which the wind pattern moves horizontally.")]
public float windNoiseSpeed = 1;
[Tooltip("The wind intensity will be between this value and 'Wind Intensity To'.")]
public float windIntensityFrom = -0.4f;
private float lastWindIntensityFrom;
[Tooltip("The wind intensity will be between this value and 'Wind Intensity From'.")]
public float windIntensityTo = 0.4f;
private float lastWindIntensityTo;
//Runtime:
float currentTime;
void Start()
{
currentTime = 0;
}
void FixedUpdate()
{
ModifyIfChanged(ref windNoiseScale,ref lastWindNoiseScale, "WindNoiseScale");
ModifyIfChanged(ref windIntensityFrom, ref lastWindIntensityFrom, "WindMinIntensity");
ModifyIfChanged(ref windIntensityTo, ref lastWindIntensityTo, "WindMaxIntensity");
currentTime += Time.fixedDeltaTime * windNoiseSpeed;
Shader.SetGlobalFloat("WindTime", currentTime);
}
public void ModifyIfChanged(ref float currentValue, ref float oldValue, string globalShaderName)
{
if(oldValue != currentValue)
{
oldValue = currentValue;
Shader.SetGlobalFloat(globalShaderName, currentValue);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 22dc68242d36c804f80751218b65e768
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 394972c0895cd9d49a5892a6c9c9ac2d, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,21 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace SpriteShadersUltimate
{
public class WindParallaxSSU : MonoBehaviour
{
float originalXPosition;
void Awake()
{
originalXPosition = transform.position.x;
}
void Start()
{
GetComponent<Renderer>().material.SetFloat("_WindXPosition", originalXPosition);
}
}
}

View File

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

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f62aa1a1edb4481458b75e386456a138
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,14 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace SpriteShadersUltimate
{
[DisallowMultipleComponent()]
public class InstancerSSU : MonoBehaviour
{
//To prevent multiple components of subtypes.
[HideInInspector]
public Material runtimeMaterial;
}
}

View File

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

View File

@@ -0,0 +1,33 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace SpriteShadersUltimate
{
public class MaterialInstancerSSU : InstancerSSU
{
void Awake()
{
Graphic graphic = GetComponent<Graphic>();
if(graphic != null)
{
graphic.material = Instantiate(graphic.material);
runtimeMaterial = graphic.materialForRendering;
}
Renderer renderer = GetComponent<Renderer>();
if(renderer != null)
{
Material[] materials = renderer.sharedMaterials;
for(int n = 0; n < materials.Length; n++)
{
materials[n] = Instantiate(materials[n]);
}
renderer.materials = renderer.sharedMaterials = materials;
runtimeMaterial = materials[0];
}
}
}
}

View File

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

View File

@@ -0,0 +1,282 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace SpriteShadersUltimate
{
public class ShaderFaderSSU : MonoBehaviour
{
//Fading:
public bool automaticFading = true;
public bool isFaded;
[Range(0, 1)]
public float fadeValue = 0f;
[Min(0.01f)]
public float duration = 2f;
public bool unscaledTime;
public AnimationCurve fadeCurve = new AnimationCurve(new Keyframe(0, 0, 0, 0, 0.55f, 0.55f), new Keyframe(1, 1, 0, 0, 0.55f, 0.55f));
//Materials:
public bool getChildObjects = true;
public bool poolMaterials = true;
public List<Renderer> renderers = new List<Renderer>();
public List<Graphic> graphics = new List<Graphic>();
//Properties:
public List<FloatFaderSSU> floatProperties = new List<FloatFaderSSU>();
public List<VectorFaderSSU> vectorProperties = new List<VectorFaderSSU>();
public List<ColorFaderSSU> colorProperties = new List<ColorFaderSSU>();
//Internal:
HashSet<Material> materials;
Dictionary<Material, Material> materialPool;
float lastFadeValue;
void Start()
{
ReloadMaterials();
}
void Update()
{
//Fade:
if(automaticFading)
{
if(isFaded)
{
float speed = 1f / duration;
fadeValue += unscaledTime ? Time.unscaledDeltaTime * speed : Time.deltaTime * speed;
if(fadeValue > 1f)
{
fadeValue = 1f;
}
}
else
{
float speed = 1f / duration;
fadeValue -= unscaledTime ? Time.unscaledDeltaTime * speed : Time.deltaTime * speed;
if (fadeValue < 0f)
{
fadeValue = 0f;
}
}
}
//Update Materials:
if(lastFadeValue != fadeValue)
{
lastFadeValue = fadeValue;
UpdateMaterials();
}
}
public void UpdateMaterials()
{
foreach (Material mat in materials)
{
UpdateSingleMaterial(mat, fadeValue);
}
}
public void UpdateSingleMaterial(Material mat, float fadeFactor)
{
foreach (FloatFaderSSU floatProperty in floatProperties)
{
mat.SetFloat(floatProperty.propertyName, Mathf.LerpUnclamped(floatProperty.fromValue, floatProperty.toValue, ApplyTimeRange(fadeFactor, floatProperty.fromTime, floatProperty.toTime)));
}
foreach (VectorFaderSSU vectorProperty in vectorProperties)
{
mat.SetColor(vectorProperty.propertyName, Vector4.LerpUnclamped(vectorProperty.fromValue, vectorProperty.toValue, ApplyTimeRange(fadeFactor, vectorProperty.fromTime, vectorProperty.toTime)));
}
foreach (ColorFaderSSU colorProperty in colorProperties)
{
mat.SetColor(colorProperty.propertyName, Color.LerpUnclamped(colorProperty.fromValue, colorProperty.toValue, ApplyTimeRange(fadeFactor, colorProperty.fromTime, colorProperty.toTime)));
}
}
float ApplyTimeRange(float fadeFactor, float fromTime, float toTime)
{
return fadeCurve.Evaluate(Mathf.Clamp01((fadeFactor - fromTime) / (toTime - fromTime)));
}
#region Get Materials
public void ReloadMaterials()
{
//Initialize:
materials = new HashSet<Material>();
materialPool = new Dictionary<Material, Material>();
lastFadeValue = -1;
//Get Materials:
if (getChildObjects)
{
//Auto Renderers:
foreach (Renderer renderer in gameObject.GetComponentsInChildren<Renderer>(true))
{
GetMaterialFromRenderer(renderer);
}
//Auto Graphics:
foreach (Graphic graphic in gameObject.GetComponentsInChildren<Graphic>(true))
{
GetMaterialFromGraphic(graphic);
}
}
else
{
//Manual Renderers:
if (renderers != null)
{
foreach (Renderer renderer in renderers)
{
if (renderer != null)
{
GetMaterialFromRenderer(renderer);
}
}
}
//Manual Graphics:
if (graphics != null)
{
foreach (Graphic graphic in graphics)
{
if (graphic != null)
{
GetMaterialFromGraphic(graphic);
}
}
}
}
}
void GetMaterialFromRenderer(Renderer renderer)
{
InstancerSSU instancer = renderer.GetComponent<InstancerSSU>();
if (instancer != null)
{
materials.Add(instancer.runtimeMaterial);
}
else
{
Material mat = renderer.material = InstantiateMaterial(renderer.material);
materials.Add(mat);
renderer.gameObject.AddComponent<InstancerSSU>().runtimeMaterial = mat;
}
}
void GetMaterialFromGraphic(Graphic graphic)
{
InstancerSSU instancer = graphic.GetComponent<InstancerSSU>();
if (instancer != null)
{
materials.Add(instancer.runtimeMaterial);
}
else
{
Material mat = graphic.material = InstantiateMaterial(graphic.material);
materials.Add(mat);
graphic.gameObject.AddComponent<InstancerSSU>().runtimeMaterial = mat;
}
}
Material InstantiateMaterial(Material sharedMaterial)
{
if(poolMaterials)
{
if (materialPool.ContainsKey(sharedMaterial))
{
return materialPool[sharedMaterial];
}
else
{
Material newMaterial = Instantiate<Material>(sharedMaterial);
newMaterial.name = sharedMaterial + " (Instance)";
materialPool.Add(sharedMaterial, newMaterial);
return newMaterial;
}
}
else
{
return Instantiate<Material>(sharedMaterial);
}
}
#endregion
}
[System.Serializable]
public class BaseFaderSSU
{
public BaseFaderSSU()
{
toTime = 1;
}
[Header("Property Name:")]
public string propertyName;
[Header("Time:")]
[Range(0, 1)]
public float fromTime = 0f;
[Range(0, 1)]
public float toTime = 1f;
}
[System.Serializable]
public class FloatFaderSSU : BaseFaderSSU
{
[Header("Range:")]
public float fromValue;
public float toValue;
public FloatFaderSSU(string newName, float newFrom, float newTo)
{
propertyName = newName;
fromValue = newFrom;
toValue = newTo;
fromTime = 0f;
toTime = 1f;
}
}
[System.Serializable]
public class VectorFaderSSU : BaseFaderSSU
{
[Header("Range:")]
public Vector4 fromValue;
public Vector4 toValue;
public VectorFaderSSU(string newName, Vector4 newFrom, Vector4 newTo)
{
propertyName = newName;
fromValue = newFrom;
toValue = newTo;
fromTime = 0f;
toTime = 1f;
}
}
[System.Serializable]
public class ColorFaderSSU : BaseFaderSSU
{
[Header("Range:")]
[ColorUsage(true,true)]
public Color fromValue;
[ColorUsage(true, true)]
public Color toValue;
public ColorFaderSSU(string newName, Color newFrom, Color newTo)
{
propertyName = newName;
fromValue = newFrom;
toValue = newTo;
fromTime = 0f;
toTime = 1f;
}
}
}

View File

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

View File

@@ -0,0 +1,96 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace SpriteShadersUltimate
{
/// <summary>
/// Attach this to sprite renderers or images with a sprite shaders ultimate material.
/// Enable Sprite Sheet Fix and let this component update the Sprite Sheet Rect variable.
/// </summary>
public class SpriteSheetSSU : MonoBehaviour
{
public bool updateChanges = false;
SpriteRenderer spriteRenderer;
Image image;
Sprite lastSprite;
void Awake()
{
//References:
spriteRenderer = GetComponent<SpriteRenderer>();
image = GetComponent<Image>();
//Instantiate Image:
if(image != null && GetComponent<InstancerSSU>() == null)
{
image.material = Instantiate<Material>(image.material);
}
//Update Rect:
UpdateSpriteRect();
//Disable if updateChanges is disabled.
if(updateChanges == false)
{
enabled = false;
}
}
void LateUpdate()
{
if((spriteRenderer != null && lastSprite != spriteRenderer.sprite) || (image != null && lastSprite != image.sprite))
{
UpdateSpriteRect();
}
}
public void UpdateSpriteRect()
{
if (spriteRenderer != null)
{
lastSprite = spriteRenderer.sprite;
}
else if (image != null)
{
lastSprite = image.sprite;
}
if (lastSprite != null)
{
if (spriteRenderer != null)
{
if(spriteRenderer.HasPropertyBlock())
{
MaterialPropertyBlock mpb = new MaterialPropertyBlock();
spriteRenderer.GetPropertyBlock(mpb);
mpb.SetVector("_SpriteSheetRect", GetSheetVector(lastSprite));
spriteRenderer.SetPropertyBlock(mpb);
}
else
{
spriteRenderer.material.SetVector("_SpriteSheetRect", GetSheetVector(lastSprite));
}
}
else if (image != null)
{
image.materialForRendering.SetVector("_SpriteSheetRect", GetSheetVector(lastSprite));
}
}
}
public static Vector4 GetSheetVector(Sprite sprite)
{
Rect rect = sprite.rect;
Texture text = sprite.texture;
float width = text.width;
float height = text.height;
Vector2 minVector = rect.min;
Vector2 maxVector = rect.max;
return new Vector4(minVector.x / width, minVector.y / height, maxVector.x / width, maxVector.y / height);
}
}
}

View File

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

View File

@@ -0,0 +1,24 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace SpriteShadersUltimate
{
public class UnscaledTimeSSU : MonoBehaviour
{
public bool dontDestroyOnLoad;
void Awake()
{
if(dontDestroyOnLoad)
{
DontDestroyOnLoad(gameObject);
}
}
void Update()
{
Shader.SetGlobalFloat("UnscaledTime", Time.unscaledTime);
}
}
}

View File

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