Insanely huge initial commit

This commit is contained in:
2026-02-21 17:04:05 -08:00
parent 9cdd36191a
commit 613d75914a
22525 changed files with 4035207 additions and 0 deletions

View File

@@ -0,0 +1,96 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace AllIn1SpriteShader
{
[ExecuteInEditMode]
public class All1CreateUnifiedOutline : MonoBehaviour
{
[SerializeField] private Material outlineMaterial = null;
[SerializeField] private Transform outlineParentTransform = null;
[Space]
[Header("Only needed if Sprite (ignored if UI)")]
[SerializeField] private int duplicateOrderInLayer = -100;
[SerializeField] private string duplicateSortingLayer = "Default";
[Space]
[Header("This operation will delete the component")]
[SerializeField] private bool createUnifiedOutline;
void Update()
{
if (createUnifiedOutline)
{
if (outlineMaterial == null)
{
createUnifiedOutline = false;
MissingMaterial();
return;
}
List<Transform> children = new List<Transform>();
GetAllChildren(transform, ref children);
foreach (Transform t in children) CreateOutlineSpriteDuplicate(t.gameObject);
CreateOutlineSpriteDuplicate(gameObject);
DestroyImmediate(this);
}
}
private void CreateOutlineSpriteDuplicate(GameObject target)
{
bool objectIsUi = false;
SpriteRenderer ownSr = target.GetComponent<SpriteRenderer>();
Image ownImage = target.GetComponent<Image>();
if (ownSr != null) objectIsUi = false;
else if (ownImage != null) objectIsUi = true;
else if (ownSr == null && ownImage == null && !transform.Equals(outlineParentTransform)) return;
GameObject objDuplicate = new GameObject();
objDuplicate.name = target.name + "Outline";
objDuplicate.transform.position = target.transform.position;
objDuplicate.transform.rotation = target.transform.rotation;
objDuplicate.transform.localScale = target.transform.lossyScale;
if (outlineParentTransform == null) objDuplicate.transform.parent = target.transform;
else objDuplicate.transform.parent = outlineParentTransform;
if (!objectIsUi)
{
SpriteRenderer sr = objDuplicate.AddComponent<SpriteRenderer>();
sr.sprite = ownSr.sprite;
sr.sortingOrder = duplicateOrderInLayer;
sr.sortingLayerName = duplicateSortingLayer;
sr.material = outlineMaterial;
sr.flipX = ownSr.flipX;
sr.flipY = ownSr.flipY;
}
else
{
Image image = objDuplicate.AddComponent<Image>();
image.sprite = ownImage.sprite;
image.material = outlineMaterial;
}
}
private void MissingMaterial()
{
#if UNITY_EDITOR
EditorUtility.DisplayDialog("Missing Material", "Please assign a Material For New Duplicate and try again", "Ok");
#endif
}
private void GetAllChildren(Transform parent, ref List<Transform> transforms)
{
foreach (Transform child in parent)
{
transforms.Add(child);
GetAllChildren(child, ref transforms);
}
}
}
}

View File

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

View File

@@ -0,0 +1,856 @@
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;
using UnityEngine.Tilemaps;
using UnityEngine.UI;
#if UNITY_EDITOR
using UnityEditor.SceneManagement;
#endif
namespace AllIn1SpriteShader
{
[ExecuteInEditMode]
[DisallowMultipleComponent]
[AddComponentMenu("AllIn1SpriteShader/AddAllIn1Shader")]
public class AllIn1Shader : MonoBehaviour
{
public enum ShaderTypes
{
Default,
ScaledTime,
MaskedUI,
Urp2dRenderer,
Invalid
}
public ShaderTypes shaderTypes = ShaderTypes.Invalid;
private Material currMaterial, prevMaterial;
private bool matAssigned = false, destroyed = false;
private enum AfterSetAction { Clear, CopyMaterial, Reset};
[Range(1f, 20f)] public float normalStrength = 5f;
[Range(0f, 3f)] public int normalSmoothing = 1;
[HideInInspector] public bool computingNormal = false;
#if UNITY_EDITOR
private static float timeLastReload = -1f;
private void Start()
{
if(timeLastReload < 0) timeLastReload = Time.time;
}
private void Update()
{
if (matAssigned || Application.isPlaying || !gameObject.activeSelf) return;
Renderer sr = GetComponent<Renderer>();
if (sr != null)
{
if (sr.sharedMaterial == null)
{
CleanMaterial();
MakeNewMaterial(true);
}
if (sr.sharedMaterial.name.Contains("Default")) MakeNewMaterial(true);
else matAssigned = true;
}
else
{
Graphic img = GetComponent<Graphic>();
if (img != null)
{
if (img.material.name.Contains("Default")) MakeNewMaterial(true);
else matAssigned = true;
}
}
}
#endif
private void MakeNewMaterial(bool getShaderTypeFromPrefs, string shaderName = "AllIn1SpriteShader")
{
SetMaterial(AfterSetAction.Clear, getShaderTypeFromPrefs, shaderName);
}
public void MakeCopy()
{
SetMaterial(AfterSetAction.CopyMaterial, false, GetStringFromShaderType());
}
private void ResetAllProperties(bool getShaderTypeFromPrefs, string shaderName)
{
SetMaterial(AfterSetAction.Reset, getShaderTypeFromPrefs, shaderName);
}
private string GetStringFromShaderType()
{
if (shaderTypes == ShaderTypes.Default) return "AllIn1SpriteShader";
else if (shaderTypes == ShaderTypes.ScaledTime) return "AllIn1SpriteShaderScaledTime";
else if (shaderTypes == ShaderTypes.MaskedUI) return "AllIn1SpriteShaderUiMask";
else if (shaderTypes == ShaderTypes.Urp2dRenderer) return "AllIn1Urp2dRenderer";
else return "AllIn1SpriteShader";
}
private void SetMaterial(AfterSetAction action, bool getShaderTypeFromPrefs, string shaderName)
{
Shader allIn1Shader = Resources.Load(shaderName, typeof(Shader)) as Shader;
if (getShaderTypeFromPrefs)
{
int shaderVariant = PlayerPrefs.GetInt("allIn1DefaultShader");
if (shaderVariant == 1) allIn1Shader = Resources.Load("AllIn1SpriteShaderScaledTime", typeof(Shader)) as Shader;
else if (shaderVariant == 2) allIn1Shader = Resources.Load("AllIn1SpriteShaderUiMask", typeof(Shader)) as Shader;
else if (shaderVariant == 3) allIn1Shader = Resources.Load("AllIn1Urp2dRenderer", typeof(Shader)) as Shader;
}
if (!Application.isPlaying && Application.isEditor && allIn1Shader != null)
{
bool rendererExists = false;
Renderer sr = GetComponent<Renderer>();
if (sr != null)
{
rendererExists = true;
int renderingQueue = 3000;
if(action == AfterSetAction.CopyMaterial) renderingQueue = GetComponent<Renderer>().sharedMaterial.renderQueue;
prevMaterial = new Material(GetComponent<Renderer>().sharedMaterial);
currMaterial = new Material(allIn1Shader);
currMaterial.renderQueue = renderingQueue;
GetComponent<Renderer>().sharedMaterial = currMaterial;
GetComponent<Renderer>().sharedMaterial.hideFlags = HideFlags.None;
matAssigned = true;
DoAfterSetAction(action);
}
else
{
Graphic img = GetComponent<Graphic>();
if (img != null)
{
rendererExists = true;
int renderingQueue = 3000;
if(action == AfterSetAction.CopyMaterial) renderingQueue = img.material.renderQueue;
prevMaterial = new Material(img.material);
currMaterial = new Material(allIn1Shader);
currMaterial.renderQueue = renderingQueue;
img.material = currMaterial;
img.material.hideFlags = HideFlags.None;
matAssigned = true;
DoAfterSetAction(action);
}
}
if (!rendererExists)
{
MissingRenderer();
return;
}
else
{
SetSceneDirty();
}
}
else if (allIn1Shader == null)
{
Debug.LogError("Make sure the AllIn1SpriteShader shader variants are inside the Resource folder!");
}
}
private void DoAfterSetAction(AfterSetAction action)
{
switch (action)
{
case AfterSetAction.Clear:
ClearAllKeywords();
break;
case AfterSetAction.CopyMaterial:
currMaterial.CopyPropertiesFromMaterial(prevMaterial);
break;
}
}
public void TryCreateNew()
{
bool rendererExists = false;
Renderer sr = GetComponent<Renderer>();
if (sr != null)
{
rendererExists = true;
if (sr != null && sr.sharedMaterial != null && sr.sharedMaterial.name.Contains("AllIn1"))
{
ResetAllProperties(false, GetStringFromShaderType());
ClearAllKeywords();
}
else
{
CleanMaterial();
MakeNewMaterial(false, GetStringFromShaderType());
}
}
else
{
Graphic img = GetComponent<Graphic>();
if (img != null)
{
rendererExists = true;
if (img.material.name.Contains("AllIn1"))
{
ResetAllProperties(false, GetStringFromShaderType());
ClearAllKeywords();
}
else MakeNewMaterial(false, GetStringFromShaderType());
}
}
if (!rendererExists)
{
MissingRenderer();
}
SetSceneDirty();
}
public void ClearAllKeywords()
{
SetKeyword("RECTSIZE_ON");
SetKeyword("OFFSETUV_ON");
SetKeyword("CLIPPING_ON");
SetKeyword("POLARUV_ON");
SetKeyword("TWISTUV_ON");
SetKeyword("ROTATEUV_ON");
SetKeyword("FISHEYE_ON");
SetKeyword("PINCH_ON");
SetKeyword("SHAKEUV_ON");
SetKeyword("WAVEUV_ON");
SetKeyword("ROUNDWAVEUV_ON");
SetKeyword("DOODLE_ON");
SetKeyword("ZOOMUV_ON");
SetKeyword("FADE_ON");
SetKeyword("TEXTURESCROLL_ON");
SetKeyword("GLOW_ON");
SetKeyword("OUTBASE_ON");
SetKeyword("ONLYOUTLINE_ON");
SetKeyword("OUTTEX_ON");
SetKeyword("OUTDIST_ON");
SetKeyword("DISTORT_ON");
SetKeyword("WIND_ON");
SetKeyword("GRADIENT_ON");
SetKeyword("GRADIENT2COL_ON");
SetKeyword("RADIALGRADIENT_ON");
SetKeyword("COLORSWAP_ON");
SetKeyword("HSV_ON");
SetKeyword("HITEFFECT_ON");
SetKeyword("PIXELATE_ON");
SetKeyword("NEGATIVE_ON");
SetKeyword("GRADIENTCOLORRAMP_ON");
SetKeyword("COLORRAMP_ON");
SetKeyword("GREYSCALE_ON");
SetKeyword("POSTERIZE_ON");
SetKeyword("BLUR_ON");
SetKeyword("MOTIONBLUR_ON");
SetKeyword("GHOST_ON");
SetKeyword("ALPHAOUTLINE_ON");
SetKeyword("INNEROUTLINE_ON");
SetKeyword("ONLYINNEROUTLINE_ON");
SetKeyword("HOLOGRAM_ON");
SetKeyword("CHROMABERR_ON");
SetKeyword("GLITCH_ON");
SetKeyword("FLICKER_ON");
SetKeyword("SHADOW_ON");
SetKeyword("SHINE_ON");
SetKeyword("CONTRAST_ON");
SetKeyword("OVERLAY_ON");
SetKeyword("OVERLAYMULT_ON");
SetKeyword("ALPHACUTOFF_ON");
SetKeyword("ALPHAROUND_ON");
SetKeyword("CHANGECOLOR_ON");
SetKeyword("CHANGECOLOR2_ON");
SetKeyword("CHANGECOLOR3_ON");
SetKeyword("FOG_ON");
SetSceneDirty();
}
private void SetKeyword(string keyword, bool state = false)
{
if (destroyed) return;
if (currMaterial == null)
{
FindCurrMaterial();
if (currMaterial == null)
{
MissingRenderer();
return;
}
}
if (!state) currMaterial.DisableKeyword(keyword);
else currMaterial.EnableKeyword(keyword);
}
private void FindCurrMaterial()
{
Renderer sr = GetComponent<Renderer>();
if (sr != null)
{
currMaterial = GetComponent<Renderer>().sharedMaterial;
matAssigned = true;
}
else
{
Graphic img = GetComponent<Graphic>();
if (img != null)
{
currMaterial = img.material;
matAssigned = true;
}
}
}
public void CleanMaterial()
{
Renderer sr = GetComponent<Renderer>();
if (sr != null)
{
sr.sharedMaterial = new Material(Shader.Find("Sprites/Default"));
matAssigned = false;
}
else
{
Graphic img = GetComponent<Graphic>();
if (img != null)
{
img.material = new Material(Shader.Find("Sprites/Default"));
matAssigned = false;
}
}
SetSceneDirty();
}
public void SaveMaterial()
{
#if UNITY_EDITOR
string sameMaterialPath = AllIn1ShaderWindow.materialsSavesPath;
if (PlayerPrefs.HasKey("All1ShaderMaterials")) sameMaterialPath = PlayerPrefs.GetString("All1ShaderMaterials");
else PlayerPrefs.SetString("All1ShaderMaterials", AllIn1ShaderWindow.materialsSavesPath);
sameMaterialPath += "/";
if (!System.IO.Directory.Exists(sameMaterialPath))
{
EditorUtility.DisplayDialog("The desired Material Save Path doesn't exist",
"Go to Window -> AllIn1ShaderWindow and set a valid folder", "Ok");
return;
}
sameMaterialPath += gameObject.name;
string fullPath = sameMaterialPath + ".mat";
if (System.IO.File.Exists(fullPath))
{
SaveMaterialWithOtherName(sameMaterialPath);
}
else DoSaving(fullPath);
SetSceneDirty();
#endif
}
private void SaveMaterialWithOtherName(string path, int i = 1)
{
int number = i;
string newPath = path + "_" + number.ToString();
string fullPath = newPath + ".mat";
if (System.IO.File.Exists(fullPath))
{
number++;
SaveMaterialWithOtherName(path, number);
}
else
{
DoSaving(fullPath);
}
}
private void DoSaving(string fileName)
{
#if UNITY_EDITOR
bool rendererExists = false;
Renderer sr = GetComponent<Renderer>();
Material matToSave = null;
Material createdMat = null;
if (sr != null)
{
rendererExists = true;
matToSave = sr.sharedMaterial;
}
else
{
Graphic img = GetComponent<Graphic>();
if (img != null)
{
rendererExists = true;
matToSave = img.material;
}
}
if (!rendererExists)
{
MissingRenderer();
return;
}
else
{
createdMat = new Material(matToSave);
currMaterial = createdMat;
AssetDatabase.CreateAsset(createdMat, fileName);
Debug.Log(fileName + " has been saved!");
EditorGUIUtility.PingObject(AssetDatabase.LoadAssetAtPath(fileName, typeof(Material)));
}
if (sr != null)
{
sr.material = createdMat;
}
else
{
Graphic img = GetComponent<Graphic>();
img.material = createdMat;
}
#endif
}
public void SetSceneDirty()
{
#if UNITY_EDITOR
if (!Application.isPlaying) EditorSceneManager.MarkAllScenesDirty();
//If you get an error here please delete the 2 lines below
var prefabStage = UnityEditor.SceneManagement.PrefabStageUtility.GetCurrentPrefabStage();
if (prefabStage != null) EditorSceneManager.MarkSceneDirty(prefabStage.scene);
#endif
}
private void MissingRenderer()
{
#if UNITY_EDITOR
EditorUtility.DisplayDialog("Missing Renderer", "This GameObject (" +
gameObject.name + ") has no Renderer or UI Image component. This AllIn1Shader component will be removed.", "Ok");
destroyed = true;
DestroyImmediate(this);
#endif
}
public void ToggleSetAtlasUvs(bool activate)
{
SetAtlasUvs atlasUvs = GetComponent<SetAtlasUvs>();
if (activate)
{
if (atlasUvs == null) atlasUvs = gameObject.AddComponent<SetAtlasUvs>();
atlasUvs.GetAndSetUVs();
SetKeyword("ATLAS_ON", true);
}
else
{
if (atlasUvs != null)
{
atlasUvs.ResetAtlasUvs();
DestroyImmediate(atlasUvs);
}
SetKeyword("ATLAS_ON", false);
}
SetSceneDirty();
}
public void ApplyMaterialToHierarchy()
{
Renderer sr = GetComponent<Renderer>();
Graphic image = GetComponent<Graphic>();
Material matToApply = null;
if (sr != null) matToApply = sr.sharedMaterial;
else if (image != null)
{
matToApply = image.material;
}
else
{
MissingRenderer();
return;
}
List<Transform> children = new List<Transform>();
GetAllChildren(transform, ref children);
foreach (Transform t in children)
{
sr = t.gameObject.GetComponent<Renderer>();
if (sr != null) sr.material = matToApply;
else
{
image = t.gameObject.GetComponent<Graphic>();
if (image != null) image.material = matToApply;
}
}
}
public void CheckIfValidTarget()
{
Renderer sr = GetComponent<Renderer>();
Graphic image = GetComponent<Graphic>();
if (sr == null && image == null) MissingRenderer();
}
private void GetAllChildren(Transform parent, ref List<Transform> transforms)
{
foreach (Transform child in parent)
{
transforms.Add(child);
GetAllChildren(child, ref transforms);
}
}
public void RenderToImage()
{
#if UNITY_EDITOR
if (currMaterial == null)
{
FindCurrMaterial();
if (currMaterial == null)
{
MissingRenderer();
return;
}
}
Texture tex = currMaterial.GetTexture("_MainTex");
if (tex != null) RenderAndSaveTexture(currMaterial, tex);
else
{
SpriteRenderer sr = GetComponent<SpriteRenderer>();
Graphic i = GetComponent<Graphic>();
if (sr != null) tex = sr.sprite.texture;
else if (i != null) tex = i.mainTexture;
if (tex != null) RenderAndSaveTexture(currMaterial, tex);
else EditorUtility.DisplayDialog("No valid target texture found", "All In 1 Shader component couldn't find a valid Main Texture in this GameObject (" +
gameObject.name + "). This means that the material you are using has no Main Texture or that the texture couldn't be reached through the Renderer component you are using." +
" Please make sure to have a valid Main Texture in the Material", "Ok");
}
#endif
}
public void RenderAndSaveTexture(Material targetMaterial, Texture targetTexture)
{
#if UNITY_EDITOR
float scaleSlider = 1;
if (PlayerPrefs.HasKey("All1ShaderRenderImagesScale")) scaleSlider = PlayerPrefs.GetFloat("All1ShaderRenderImagesScale");
RenderTexture renderTarget = new RenderTexture((int)(targetTexture.width * scaleSlider), (int)(targetTexture.height * scaleSlider), 0, RenderTextureFormat.ARGB32);
Graphics.Blit(targetTexture, renderTarget, targetMaterial);
Texture2D reaultTex = new Texture2D(renderTarget.width, renderTarget.height, TextureFormat.ARGB32, false);
reaultTex.ReadPixels(new Rect(0, 0, renderTarget.width, renderTarget.height), 0, 0);
reaultTex.Apply();
string path = AllIn1ShaderWindow.renderImagesSavesPath;
if (PlayerPrefs.HasKey("All1ShaderRenderImages")) path = PlayerPrefs.GetString("All1ShaderRenderImages");
else PlayerPrefs.SetString("All1ShaderRenderImages", AllIn1ShaderWindow.renderImagesSavesPath);
path += "/";
if (!System.IO.Directory.Exists(path))
{
EditorUtility.DisplayDialog("The desired Material to Image Save Path doesn't exist",
"Go to Window -> AllIn1ShaderWindow and set a valid folder", "Ok");
return;
}
string fullPath = path + gameObject.name + ".png";
if (System.IO.File.Exists(fullPath)) fullPath = GetNewValidPath(path + gameObject.name);
string pingPath = fullPath;
string fileName = fullPath.Replace(path, "");
fileName = fileName.Replace(".png", "");
fullPath = EditorUtility.SaveFilePanel("Save Render Image", path, fileName, "png");
byte[] bytes = reaultTex.EncodeToPNG();
File.WriteAllBytes(fullPath, bytes);
AssetDatabase.ImportAsset(subPath);
AssetDatabase.Refresh();
DestroyImmediate(reaultTex);
EditorGUIUtility.PingObject(AssetDatabase.LoadAssetAtPath(pingPath, typeof(Texture)));
Debug.Log("Render Image saved to: " + fullPath + " with scale: " + scaleSlider + " (it can be changed in Window -> AllIn1ShaderWindow)");
#endif
}
private string GetNewValidPath(string path, int i = 1)
{
int number = i;
string newPath = path + "_" + number.ToString();
string fullPath = newPath + ".png";
if (System.IO.File.Exists(fullPath))
{
number++;
fullPath = GetNewValidPath(path, number);
}
return fullPath;
}
#region normalMapCreator
protected virtual void OnEnable()
{
#if UNITY_EDITOR
EditorApplication.update += OnEditorUpdate;
#endif
}
protected virtual void OnDisable()
{
#if UNITY_EDITOR
EditorApplication.update -= OnEditorUpdate;
#endif
}
bool needToWait;
int waitingCycles;
int timesWeWaited;
protected virtual void OnEditorUpdate()
{
if (computingNormal)
{
if (needToWait)
{
waitingCycles++;
if (waitingCycles > 5)
{
needToWait = false;
timesWeWaited++;
}
}
else
{
if (timesWeWaited == 1) SetNewNormalTexture2();
if (timesWeWaited == 2) SetNewNormalTexture3();
if (timesWeWaited == 3) SetNewNormalTexture4();
needToWait = true;
}
}
}
SpriteRenderer normalMapSr;
Renderer normalMapRenderer;
bool isSpriteRenderer;
public void CreateAndAssignNormalMap()
{
#if UNITY_EDITOR
if (GetComponent<TilemapRenderer>() != null)
{
EditorUtility.DisplayDialog("This is a tilemap", "This feature isn't supported on Tilemap Renderers." +
" Add a secondary normal map texture instead (you can create a Normal Map in the asset Window)", "Ok");
return;
}
normalMapSr = GetComponent<SpriteRenderer>();
normalMapRenderer = GetComponent<Renderer>();
if (normalMapSr != null)
{
isSpriteRenderer = true;
SetNewNormalTexture();
}
else if (normalMapRenderer != null)
{
isSpriteRenderer = false;
SetNewNormalTexture();
}
else
{
if (GetComponent<Graphic>() != null)
{
EditorUtility.DisplayDialog("This is a UI element", "This GameObject (" +
gameObject.name + ") is a UI element. UI elements probably shouldn't have a normal map. Why are you using the light shader variant?", "Ok");
}
else
{
MissingRenderer();
}
return;
}
#endif
}
string path;
private void SetNewNormalTexture()
{
#if UNITY_EDITOR
path = AllIn1ShaderWindow.normalMapSavesPath;
if (PlayerPrefs.HasKey("All1ShaderNormals")) path = PlayerPrefs.GetString("All1ShaderNormals");
else PlayerPrefs.SetString("All1ShaderNormals", AllIn1ShaderWindow.normalMapSavesPath);
path += "/";
if (!System.IO.Directory.Exists(path))
{
EditorUtility.DisplayDialog("The desired folder doesn't exist",
"Go to Window -> AllIn1ShaderWindow and set a valid folder", "Ok");
return;
}
#else
computingNormal = false;
return;
#endif
computingNormal = true;
needToWait = true;
waitingCycles = 0;
timesWeWaited = 0;
}
#if UNITY_EDITOR
TextureImporter importer;
Texture2D mainTex2D;
#endif
private void SetNewNormalTexture2()
{
#if UNITY_EDITOR
if (!isSpriteRenderer)
{
mainTex2D = (Texture2D)normalMapRenderer.sharedMaterial.GetTexture("_MainTex");
importer = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(mainTex2D)) as TextureImporter;
}
else importer = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(normalMapSr.sprite)) as TextureImporter;
importer.isReadable = true;
importer.SaveAndReimport();
#endif
}
string subPath;
private void SetNewNormalTexture3()
{
#if UNITY_EDITOR
Texture2D normalM = null;
if (isSpriteRenderer) normalM = CreateNormalMap(normalMapSr.sprite.texture, normalStrength, normalSmoothing);
else normalM = CreateNormalMap(mainTex2D, normalStrength, normalSmoothing);
byte[] bytes = normalM.EncodeToPNG();
path += gameObject.name;
subPath = path + ".png";
string dataPath = Application.dataPath;
dataPath = dataPath.Replace("/Assets", "/");
string fullPath = dataPath + subPath;
File.WriteAllBytes(fullPath, bytes);
AssetDatabase.ImportAsset(subPath);
AssetDatabase.Refresh();
DestroyImmediate(normalM);
#endif
}
private void SetNewNormalTexture4()
{
#if UNITY_EDITOR
importer = AssetImporter.GetAtPath(subPath) as TextureImporter;
importer.filterMode = FilterMode.Bilinear;
importer.textureType = TextureImporterType.NormalMap;
importer.wrapMode = TextureWrapMode.Repeat;
importer.SaveAndReimport();
if (currMaterial == null)
{
FindCurrMaterial();
if (currMaterial == null)
{
MissingRenderer();
return;
}
}
Texture2D normalTex = (Texture2D)AssetDatabase.LoadAssetAtPath(subPath, typeof(Texture2D));
currMaterial.SetTexture("_NormalMap", normalTex);
Debug.Log("Normal texture saved to: " + subPath);
EditorGUIUtility.PingObject(AssetDatabase.LoadAssetAtPath(subPath, typeof(Texture)));
computingNormal = false;
#endif
}
private Texture2D CreateNormalMap(Texture2D t, float normalMult = 5f, int normalSmooth = 0)
{
Color[] pixels = new Color[t.width * t.height];
Texture2D texNormal = new Texture2D(t.width, t.height, TextureFormat.RGB24, false, false);
Vector3 vScale = new Vector3(0.3333f, 0.3333f, 0.3333f);
for (int y = 0; y < t.height; y++)
{
for (int x = 0; x < t.width; x++)
{
Color tc = t.GetPixel(x - 1, y - 1);
Vector3 cSampleNegXNegY = new Vector3(tc.r, tc.g, tc.g);
tc = t.GetPixel(x, y - 1);
Vector3 cSampleZerXNegY = new Vector3(tc.r, tc.g, tc.g);
tc = t.GetPixel(x + 1, y - 1);
Vector3 cSamplePosXNegY = new Vector3(tc.r, tc.g, tc.g);
tc = t.GetPixel(x - 1, y);
Vector3 cSampleNegXZerY = new Vector3(tc.r, tc.g, tc.g);
tc = t.GetPixel(x + 1, y);
Vector3 cSamplePosXZerY = new Vector3(tc.r, tc.g, tc.g);
tc = t.GetPixel(x - 1, y + 1);
Vector3 cSampleNegXPosY = new Vector3(tc.r, tc.g, tc.g);
tc = t.GetPixel(x, y + 1);
Vector3 cSampleZerXPosY = new Vector3(tc.r, tc.g, tc.g);
tc = t.GetPixel(x + 1, y + 1);
Vector3 cSamplePosXPosY = new Vector3(tc.r, tc.g, tc.g);
float fSampleNegXNegY = Vector3.Dot(cSampleNegXNegY, vScale);
float fSampleZerXNegY = Vector3.Dot(cSampleZerXNegY, vScale);
float fSamplePosXNegY = Vector3.Dot(cSamplePosXNegY, vScale);
float fSampleNegXZerY = Vector3.Dot(cSampleNegXZerY, vScale);
float fSamplePosXZerY = Vector3.Dot(cSamplePosXZerY, vScale);
float fSampleNegXPosY = Vector3.Dot(cSampleNegXPosY, vScale);
float fSampleZerXPosY = Vector3.Dot(cSampleZerXPosY, vScale);
float fSamplePosXPosY = Vector3.Dot(cSamplePosXPosY, vScale);
float edgeX = (fSampleNegXNegY - fSamplePosXNegY) * 0.25f + (fSampleNegXZerY - fSamplePosXZerY) * 0.5f + (fSampleNegXPosY - fSamplePosXPosY) * 0.25f;
float edgeY = (fSampleNegXNegY - fSampleNegXPosY) * 0.25f + (fSampleZerXNegY - fSampleZerXPosY) * 0.5f + (fSamplePosXNegY - fSamplePosXPosY) * 0.25f;
Vector2 vEdge = new Vector2(edgeX, edgeY) * normalMult;
Vector3 norm = new Vector3(vEdge.x, vEdge.y, 1.0f).normalized;
Color c = new Color(norm.x * 0.5f + 0.5f, norm.y * 0.5f + 0.5f, norm.z * 0.5f + 0.5f, 1);
pixels[x + y * t.width] = c;
}
}
if (normalSmooth > 0f)
{
float step = 0.00390625f * normalSmooth;
for (int y = 0; y < t.height; y++)
{
for (int x = 0; x < t.width; x++)
{
float pixelsToAverage = 0.0f;
Color c = pixels[(x + 0) + ((y + 0) * t.width)];
pixelsToAverage++;
if (x - normalSmooth > 0)
{
if (y - normalSmooth > 0)
{
c += pixels[(x - normalSmooth) + ((y - normalSmooth) * t.width)];
pixelsToAverage++;
}
c += pixels[(x - normalSmooth) + ((y + 0) * t.width)];
pixelsToAverage++;
if (y + normalSmooth < t.height)
{
c += pixels[(x - normalSmooth) + ((y + normalSmooth) * t.width)];
pixelsToAverage++;
}
}
if (y - normalSmooth > 0)
{
c += pixels[(x + 0) + ((y - normalSmooth) * t.width)];
pixelsToAverage++;
}
if (y + normalSmooth < t.height)
{
c += pixels[(x + 0) + ((y + normalSmooth) * t.width)];
pixelsToAverage++;
}
if (x + normalSmooth < t.width)
{
if (y - normalSmooth > 0)
{
c += pixels[(x + normalSmooth) + ((y - normalSmooth) * t.width)];
pixelsToAverage++;
}
c += pixels[(x + normalSmooth) + ((y + 0) * t.width)];
pixelsToAverage++;
if (y + normalSmooth < t.height)
{
c += pixels[(x + normalSmooth) + ((y + normalSmooth) * t.width)];
pixelsToAverage++;
}
}
pixels[x + y * t.width] = c / pixelsToAverage;
}
}
}
texNormal.SetPixels(pixels);
texNormal.Apply();
return texNormal;
}
#endregion
}
}

View File

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

View File

@@ -0,0 +1,545 @@
#if UNITY_EDITOR
using System.IO;
using UnityEditor;
using UnityEngine;
namespace AllIn1SpriteShader
{
public class AllIn1ShaderWindow : EditorWindow
{
private const string versionString = "3.4";
[MenuItem("Window/AllIn1ShaderWindow")]
public static void ShowAllIn1ShaderWindowWindow()
{
GetWindow<AllIn1ShaderWindow>("All In 1 Shader Window");
}
public static readonly string materialsSavesPath = "Assets/AllIn1SpriteShader/Materials";
public static readonly string renderImagesSavesPath = "Assets/AllIn1SpriteShader/Textures";
public static readonly string normalMapSavesPath = "Assets/AllIn1SpriteShader/Textures/NormalMaps";
public static readonly string gradientSavesPath = "Assets/AllIn1SpriteShader/Textures/GradientTextures";
public Vector2 scrollPosition = Vector2.zero;
private DefaultAsset materialTargetFolder = null;
private GUIStyle style, bigLabel = new GUIStyle(), titleStyle = new GUIStyle();
private const int bigFontSize = 16;
enum ShaderTypes
{
Default,
ScaledTime,
MaskedUI,
Urp2dRenderer
}
ShaderTypes shaderTypes = ShaderTypes.Default;
bool showUrpWarning = false;
double warningTime = 0f;
private Texture2D targetNormalImage;
private float normalStrength = 5f;
private int normalSmoothing = 1;
private int isComputingNormals = 0;
private enum TextureSizes
{
_2 = 2,
_4 = 4,
_8 = 8,
_16 = 16,
_32 = 32,
_64 = 64,
_128 = 128,
_256 = 256,
_512 = 512,
_1024 = 1024,
_2048 = 2048
}
private TextureSizes textureSizes = TextureSizes._128;
[SerializeField] private Gradient gradient = new Gradient();
private FilterMode gradientFiltering = FilterMode.Bilinear;
private enum ImageType
{
ShowImage,
HideInComponent,
HideEverywhere
}
private ImageType imageType;
private void OnGUI()
{
style = new GUIStyle(EditorStyles.helpBox);
style.margin = new RectOffset(0, 0, 0, 0);
bigLabel = new GUIStyle(EditorStyles.boldLabel);
bigLabel.fontSize = bigFontSize;
titleStyle.alignment = TextAnchor.MiddleLeft;
using (var scrollView = new EditorGUILayout.ScrollViewScope(scrollPosition, GUILayout.Width(position.width), GUILayout.Height(position.height)))
{
scrollPosition = scrollView.scrollPosition;
ShowImageAndSetImageEditorPref();
ShowAssetImageOptionsToggle();
DefaultAssetShader();
DrawLine(Color.grey, 1, 3);
GUILayout.Label("Material Save Path", bigLabel);
GUILayout.Space(20);
GUILayout.Label("Select the folder where new Materials will be saved when the Save Material To Folder button of the asset component is pressed", EditorStyles.boldLabel);
HandleSaveFolderEditorPref("All1ShaderMaterials", materialsSavesPath, "Material");
DrawLine(Color.grey, 1, 3);
GUILayout.Label("Render Material to Image Save Path", bigLabel);
GUILayout.Space(20);
EditorGUILayout.BeginHorizontal();
{
float scaleSlider = 1;
if (PlayerPrefs.HasKey("All1ShaderRenderImagesScale")) scaleSlider = PlayerPrefs.GetFloat("All1ShaderRenderImagesScale");
GUILayout.Label("Rendered Image Texture Scale", GUILayout.MaxWidth(190));
scaleSlider = EditorGUILayout.Slider(scaleSlider, 0.2f, 5f, GUILayout.MaxWidth(200));
if (GUILayout.Button("Default Value", GUILayout.MaxWidth(100))) PlayerPrefs.SetFloat("All1ShaderRenderImagesScale", 1f);
else PlayerPrefs.SetFloat("All1ShaderRenderImagesScale", scaleSlider);
}
EditorGUILayout.EndVertical();
GUILayout.Label("Select the folder where new Images will be saved when the Render Material To Image button of the asset component is pressed", EditorStyles.boldLabel);
HandleSaveFolderEditorPref("All1ShaderRenderImages", renderImagesSavesPath, "Images");
DrawLine(Color.grey, 1, 3);
NormalMapCreator();
DrawLine(Color.grey, 1, 3);
GradientCreator();
GUILayout.Space(10);
DrawLine(Color.grey, 1, 3);
GUILayout.Label("Current asset version is " + versionString, EditorStyles.boldLabel);
}
}
private void ShowImageAndSetImageEditorPref()
{
if(!EditorPrefs.HasKey("allIn1ImageConfig"))
{
EditorPrefs.SetInt("allIn1ImageConfig", (int) ImageType.ShowImage);
}
imageType = (ImageType) EditorPrefs.GetInt("allIn1ImageConfig");
if(imageType == ImageType.HideEverywhere) return;
Texture2D imageInspector = null;
switch(imageType)
{
case ImageType.ShowImage:
{
imageInspector =
(Texture2D) AssetDatabase.LoadAssetAtPath("Assets/AllIn1SpriteShader/Textures/CustomEditorImage.png",
typeof(Texture2D));
break;
}
case ImageType.HideInComponent:
imageInspector =
(Texture2D) AssetDatabase.LoadAssetAtPath("Assets/AllIn1SpriteShader/Textures/CustomEditorImage.png",
typeof(Texture2D));
break;
}
if(imageInspector)
{
//Label title image to the right
Rect rect = EditorGUILayout.GetControlRect(false, 5, titleStyle);
GUILayout.Label(imageInspector, titleStyle, GUILayout.Height(50));
//Centered title image
//Rect rect = EditorGUILayout.GetControlRect(GUILayout.Height(50));
//GUI.DrawTexture(rect, imageInspector, ScaleMode.ScaleToFit, true);
}
DrawLine(Color.grey, 1, 3);
}
private void ShowAssetImageOptionsToggle()
{
GUILayout.Label("Asset Image Display Options", bigLabel);
GUILayout.Space(20);
int previousImageType = (int) imageType;
imageType = (ImageType) EditorGUILayout.EnumPopup(imageType, GUILayout.MaxWidth(200));
if((int) imageType != previousImageType) EditorPrefs.SetInt("allIn1ImageConfig", (int) imageType);
DrawLine(Color.grey, 1, 3);
}
private void DefaultAssetShader()
{
GUILayout.Label("Default Asset Shader", bigLabel);
GUILayout.Space(20);
GUILayout.Label("This is the shader variant that will be assinged by default to Sprites and UI Images when the asset component is added", EditorStyles.boldLabel);
bool isUrp = false;
Shader temp = Resources.Load("AllIn1Urp2dRenderer", typeof(Shader)) as Shader;
if (temp != null) isUrp = true;
shaderTypes = (ShaderTypes)PlayerPrefs.GetInt("allIn1DefaultShader");
int previousShaderType = (int)shaderTypes;
shaderTypes = (ShaderTypes)EditorGUILayout.EnumPopup(shaderTypes, GUILayout.MaxWidth(200));
if (previousShaderType != (int)shaderTypes)
{
if (!isUrp && shaderTypes == ShaderTypes.Urp2dRenderer)
{
showUrpWarning = true;
warningTime = EditorApplication.timeSinceStartup + 5;
}
else
{
PlayerPrefs.SetInt("allIn1DefaultShader", (int)shaderTypes);
showUrpWarning = false;
}
}
if (warningTime < EditorApplication.timeSinceStartup) showUrpWarning = false;
if (isUrp) showUrpWarning = false;
if (!isUrp && !showUrpWarning && shaderTypes == ShaderTypes.Urp2dRenderer)
{
showUrpWarning = true;
warningTime = EditorApplication.timeSinceStartup + 5;
shaderTypes = ShaderTypes.Default;
PlayerPrefs.SetInt("allIn1DefaultShader", (int)shaderTypes);
}
if (showUrpWarning) EditorGUILayout.HelpBox(
"You can't set the URP 2D Renderer variant since you didn't import the URP package available in the asset root folder (SEE DOCUMENTATION)",
MessageType.Error,
true);
}
private void NormalMapCreator()
{
GUILayout.Label("Normal Map Creator", bigLabel);
GUILayout.Space(20);
GUILayout.Label("Select the folder where new Normal Maps will be saved when the Create Normal Map button of the asset component is pressed (URP only)", EditorStyles.boldLabel);
HandleSaveFolderEditorPref("All1ShaderNormals", normalMapSavesPath, "Normal Maps");
GUILayout.Space(20);
GUILayout.Label("Assign a sprite you want to create a normal map from. Choose the normal map settings and press the 'Create And Save Normal Map' button", EditorStyles.boldLabel);
targetNormalImage = (Texture2D)EditorGUILayout.ObjectField("Target Image", targetNormalImage, typeof(Texture2D), false, GUILayout.MaxWidth(225));
EditorGUILayout.BeginHorizontal();
{
GUILayout.Label("Normal Strength:", GUILayout.MaxWidth(150));
normalStrength = EditorGUILayout.Slider(normalStrength, 1f, 20f, GUILayout.MaxWidth(400));
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
{
GUILayout.Label("Normal Smoothing:", GUILayout.MaxWidth(150));
normalSmoothing = EditorGUILayout.IntSlider(normalSmoothing, 0, 3, GUILayout.MaxWidth(400));
}
EditorGUILayout.EndHorizontal();
if (isComputingNormals == 0)
{
if (targetNormalImage != null)
{
if (GUILayout.Button("Create And Save Normal Map"))
{
isComputingNormals = 1;
return;
}
}
else
{
GUILayout.Label("Add a Target Image to use this feature", EditorStyles.boldLabel);
}
}
else
{
GUILayout.Label("Normal Map is currently being created, be patient", EditorStyles.boldLabel, GUILayout.Height(40));
Repaint();
isComputingNormals++;
if (isComputingNormals > 5)
{
string assetPath = AssetDatabase.GetAssetPath(targetNormalImage);
var tImporter = AssetImporter.GetAtPath(assetPath) as TextureImporter;
if (tImporter != null)
{
tImporter.isReadable = true;
tImporter.SaveAndReimport();
}
Texture2D normalToSave = CreateNormalMap(targetNormalImage, normalStrength, normalSmoothing);
string prefSavedPath = PlayerPrefs.GetString("All1ShaderNormals") + "/";
string path = prefSavedPath + "NormalMap.png";
if(System.IO.File.Exists(path)) path = GetNewValidPath(path);
string texName = path.Replace(prefSavedPath, "");
path = EditorUtility.SaveFilePanel("Save texture as PNG", prefSavedPath, texName, "png");
if (path.Length != 0)
{
byte[] pngData = normalToSave.EncodeToPNG();
if (pngData != null) File.WriteAllBytes(path, pngData);
AssetDatabase.Refresh();
if (path.IndexOf("Assets/") >= 0)
{
string subPath = path.Substring(path.IndexOf("Assets/"));
TextureImporter importer = AssetImporter.GetAtPath(subPath) as TextureImporter;
if (importer != null)
{
Debug.Log("Normal Map saved inside the project: " + subPath);
importer.filterMode = FilterMode.Bilinear;
importer.textureType = TextureImporterType.NormalMap;
importer.wrapMode = TextureWrapMode.Repeat;
importer.SaveAndReimport();
EditorGUIUtility.PingObject(AssetDatabase.LoadAssetAtPath(subPath, typeof(Texture)));
}
}
else Debug.Log("Normal Map saved outside the project: " + path);
}
isComputingNormals = 0;
}
}
GUILayout.Label("*This process will freeze the editor for some seconds, larger images will take longer", EditorStyles.boldLabel);
}
private void HandleSaveFolderEditorPref(string keyName, string defaultPath, string logsFeatureName)
{
if (!PlayerPrefs.HasKey(keyName)) PlayerPrefs.SetString(keyName, defaultPath);
materialTargetFolder = (DefaultAsset)AssetDatabase.LoadAssetAtPath(PlayerPrefs.GetString(keyName), typeof(DefaultAsset));
if (materialTargetFolder == null)
{
PlayerPrefs.SetString(keyName, defaultPath);
materialTargetFolder = (DefaultAsset)AssetDatabase.LoadAssetAtPath(PlayerPrefs.GetString(keyName), typeof(DefaultAsset));
if (materialTargetFolder == null)
{
materialTargetFolder = (DefaultAsset)AssetDatabase.LoadAssetAtPath("Assets/", typeof(DefaultAsset));
if (materialTargetFolder == null) Debug.LogError("The desired save folder doesn't exist. Go to Window -> AllIn1ShaderWindow and set a valid folder");
else PlayerPrefs.SetString("Assets/", defaultPath);
}
}
materialTargetFolder = (DefaultAsset)EditorGUILayout.ObjectField("New " + logsFeatureName + " Folder", materialTargetFolder, typeof(DefaultAsset), false);
if (materialTargetFolder != null && IsAssetAFolder(materialTargetFolder))
{
string path = AssetDatabase.GetAssetPath(materialTargetFolder);
PlayerPrefs.SetString(keyName, path);
EditorGUILayout.HelpBox("Valid folder! " + logsFeatureName + " save path: " + path, MessageType.Info, true);
}
else EditorGUILayout.HelpBox("Select the new " + logsFeatureName + " Folder", MessageType.Warning, true);
}
private void GradientCreator()
{
GUILayout.Label("Gradient Creator", bigLabel);
GUILayout.Space(20);
GUILayout.Label("This feature can be used to create textures for the Color Ramp Effect", EditorStyles.boldLabel);
EditorGUILayout.GradientField("Gradient", gradient, GUILayout.Height(25));
EditorGUILayout.BeginHorizontal();
{
GUILayout.Label("Texture Size:", GUILayout.MaxWidth(145));
textureSizes = (TextureSizes)EditorGUILayout.EnumPopup(textureSizes, GUILayout.MaxWidth(200));
}
EditorGUILayout.EndHorizontal();
int textureSize = (int)textureSizes;
Texture2D gradTex = new Texture2D(textureSize, 1, TextureFormat.RGBA32, false);
for (int i = 0; i < textureSize; i++) gradTex.SetPixel(i, 0, gradient.Evaluate((float)i / (float)textureSize));
gradTex.Apply();
GUILayout.Space(20);
GUILayout.Label("Select the folder where new Gradient Textures will be saved", EditorStyles.boldLabel);
HandleSaveFolderEditorPref("All1ShaderGradients", gradientSavesPath, "Gradient");
string prefSavedPath = PlayerPrefs.GetString("All1ShaderGradients") + "/";
if (Directory.Exists(prefSavedPath))
{
EditorGUILayout.BeginHorizontal();
{
GUILayout.Label("Gradient Texture Filtering: ", GUILayout.MaxWidth(170));
gradientFiltering = (FilterMode)EditorGUILayout.EnumPopup(gradientFiltering, GUILayout.MaxWidth(200));
}
EditorGUILayout.EndHorizontal();
if (GUILayout.Button("Save Gradient Texture"))
{
string path = prefSavedPath + "ColorGradient.png";
if(System.IO.File.Exists(path)) path = GetNewValidPath(path);
string texName = path.Replace(prefSavedPath, "");
path = EditorUtility.SaveFilePanel("Save texture as PNG", prefSavedPath, texName, "png");
if (path.Length != 0)
{
byte[] pngData = gradTex.EncodeToPNG();
if (pngData != null) File.WriteAllBytes(path, pngData);
AssetDatabase.Refresh();
if (path.IndexOf("Assets/") >= 0)
{
string subPath = path.Substring(path.IndexOf("Assets/"));
TextureImporter importer = AssetImporter.GetAtPath(subPath) as TextureImporter;
if (importer != null)
{
Debug.Log("Gradient saved inside the project: " + subPath);
importer.filterMode = gradientFiltering;
importer.SaveAndReimport();
EditorGUIUtility.PingObject(AssetDatabase.LoadAssetAtPath(subPath, typeof(Texture)));
}
}
else Debug.Log("Gradient saved outside the project: " + path);
}
}
}
}
private static bool IsAssetAFolder(Object obj)
{
string path = "";
if (obj == null) return false;
path = AssetDatabase.GetAssetPath(obj.GetInstanceID());
if (path.Length > 0)
{
if (Directory.Exists(path)) return true;
else return false;
}
return false;
}
private string GetNewValidPath(string path, int i = 1)
{
int number = i;
path = path.Replace(".png", "");
string newPath = path + "_" + number.ToString();
string fullPath = newPath + ".png";
if(System.IO.File.Exists(fullPath))
{
number++;
fullPath = GetNewValidPath(path, number);
}
return fullPath;
}
private void DrawLine(Color color, int thickness = 2, int padding = 10)
{
Rect r = EditorGUILayout.GetControlRect(GUILayout.Height(padding + thickness));
r.height = thickness;
r.y += (padding / 2);
r.x -= 2;
r.width += 6;
EditorGUI.DrawRect(r, color);
}
private Texture2D CreateNormalMap(Texture2D t, float normalMult = 5f, int normalSmooth = 0)
{
Color[] pixels = new Color[t.width * t.height];
Texture2D texNormal = new Texture2D(t.width, t.height, TextureFormat.RGB24, false, false);
Vector3 vScale = new Vector3(0.3333f, 0.3333f, 0.3333f);
for (int y = 0; y < t.height; y++)
{
for (int x = 0; x < t.width; x++)
{
Color tc = t.GetPixel(x - 1, y - 1);
Vector3 cSampleNegXNegY = new Vector3(tc.r, tc.g, tc.g);
tc = t.GetPixel(x, y - 1);
Vector3 cSampleZerXNegY = new Vector3(tc.r, tc.g, tc.g);
tc = t.GetPixel(x + 1, y - 1);
Vector3 cSamplePosXNegY = new Vector3(tc.r, tc.g, tc.g);
tc = t.GetPixel(x - 1, y);
Vector3 cSampleNegXZerY = new Vector3(tc.r, tc.g, tc.g);
tc = t.GetPixel(x + 1, y);
Vector3 cSamplePosXZerY = new Vector3(tc.r, tc.g, tc.g);
tc = t.GetPixel(x - 1, y + 1);
Vector3 cSampleNegXPosY = new Vector3(tc.r, tc.g, tc.g);
tc = t.GetPixel(x, y + 1);
Vector3 cSampleZerXPosY = new Vector3(tc.r, tc.g, tc.g);
tc = t.GetPixel(x + 1, y + 1);
Vector3 cSamplePosXPosY = new Vector3(tc.r, tc.g, tc.g);
float fSampleNegXNegY = Vector3.Dot(cSampleNegXNegY, vScale);
float fSampleZerXNegY = Vector3.Dot(cSampleZerXNegY, vScale);
float fSamplePosXNegY = Vector3.Dot(cSamplePosXNegY, vScale);
float fSampleNegXZerY = Vector3.Dot(cSampleNegXZerY, vScale);
float fSamplePosXZerY = Vector3.Dot(cSamplePosXZerY, vScale);
float fSampleNegXPosY = Vector3.Dot(cSampleNegXPosY, vScale);
float fSampleZerXPosY = Vector3.Dot(cSampleZerXPosY, vScale);
float fSamplePosXPosY = Vector3.Dot(cSamplePosXPosY, vScale);
float edgeX = (fSampleNegXNegY - fSamplePosXNegY) * 0.25f + (fSampleNegXZerY - fSamplePosXZerY) * 0.5f + (fSampleNegXPosY - fSamplePosXPosY) * 0.25f;
float edgeY = (fSampleNegXNegY - fSampleNegXPosY) * 0.25f + (fSampleZerXNegY - fSampleZerXPosY) * 0.5f + (fSamplePosXNegY - fSamplePosXPosY) * 0.25f;
Vector2 vEdge = new Vector2(edgeX, edgeY) * normalMult;
Vector3 norm = new Vector3(vEdge.x, vEdge.y, 1.0f).normalized;
Color c = new Color(norm.x * 0.5f + 0.5f, norm.y * 0.5f + 0.5f, norm.z * 0.5f + 0.5f, 1);
pixels[x + y * t.width] = c;
}
}
if (normalSmooth > 0f)
{
float step = 0.00390625f * normalSmooth;
for (int y = 0; y < t.height; y++)
{
for (int x = 0; x < t.width; x++)
{
float pixelsToAverage = 0.0f;
Color c = pixels[(x + 0) + ((y + 0) * t.width)];
pixelsToAverage++;
if (x - normalSmooth > 0)
{
if (y - normalSmooth > 0)
{
c += pixels[(x - normalSmooth) + ((y - normalSmooth) * t.width)];
pixelsToAverage++;
}
c += pixels[(x - normalSmooth) + ((y + 0) * t.width)];
pixelsToAverage++;
if (y + normalSmooth < t.height)
{
c += pixels[(x - normalSmooth) + ((y + normalSmooth) * t.width)];
pixelsToAverage++;
}
}
if (y - normalSmooth > 0)
{
c += pixels[(x + 0) + ((y - normalSmooth) * t.width)];
pixelsToAverage++;
}
if (y + normalSmooth < t.height)
{
c += pixels[(x + 0) + ((y + normalSmooth) * t.width)];
pixelsToAverage++;
}
if (x + normalSmooth < t.width)
{
if (y - normalSmooth > 0)
{
c += pixels[(x + normalSmooth) + ((y - normalSmooth) * t.width)];
pixelsToAverage++;
}
c += pixels[(x + normalSmooth) + ((y + 0) * t.width)];
pixelsToAverage++;
if (y + normalSmooth < t.height)
{
c += pixels[(x + normalSmooth) + ((y + normalSmooth) * t.width)];
pixelsToAverage++;
}
}
pixels[x + y * t.width] = c / pixelsToAverage;
}
}
}
texNormal.SetPixels(pixels);
texNormal.Apply();
return texNormal;
}
}
}
#endif

View File

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

View File

@@ -0,0 +1,37 @@
using UnityEngine;
using UnityEngine.UI;
namespace AllIn1SpriteShader
{
public class RandomSeed : MonoBehaviour
{
private readonly int randomSeedProperty = Shader.PropertyToID("_RandomSeed");
private MaterialPropertyBlock propertyBlock;
//If you want to randomize UI Images, you'll need to create different materials since materials are always shared
//This can be done at runtime with scripting or manually in the editor
private void Start()
{
Renderer renderer = GetComponent<Renderer>();
if(renderer != null)
{
propertyBlock = new MaterialPropertyBlock();
propertyBlock.SetFloat(randomSeedProperty, Random.Range(0f, 100f));
renderer.SetPropertyBlock(propertyBlock);
}
else
{
Image image = GetComponent<Image>();
if (image != null)
{
if (image.material != null)
{
image.material.SetFloat(randomSeedProperty, Random.Range(0, 1000f));
}
else Debug.LogError("Missing Material on UI Image: " + gameObject.name);
}
else Debug.LogError("Missing Renderer or UI Image on: " + gameObject.name);
}
}
}
}

View File

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

View File

@@ -0,0 +1,177 @@
using UnityEngine;
using UnityEngine.UI;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace AllIn1SpriteShader
{
[ExecuteInEditMode]
public class SetAtlasUvs : MonoBehaviour
{
[SerializeField] private bool updateEveryFrame = false;
[Tooltip("If using a Sprite Renderer it will use the material property instead of sharedMaterial"), SerializeField] private bool useMaterialInstanceIfPossible = false;
private Renderer render;
private SpriteRenderer spriteRender;
private Image uiImage;
private bool isUI = false;
private readonly int minXuv = Shader.PropertyToID("_MinXUV");
private readonly int maxXuv = Shader.PropertyToID("_MaxXUV");
private readonly int minYuv = Shader.PropertyToID("_MinYUV");
private readonly int maxYuv = Shader.PropertyToID("_MaxYUV");
private void Start()
{
Setup();
}
private void Reset()
{
Setup();
}
private void Setup()
{
if (GetRendererReferencesIfNeeded()) GetAndSetUVs();
if (!updateEveryFrame && Application.isPlaying && this != null) this.enabled = false;
}
private void OnWillRenderObject()
{
if (updateEveryFrame)
{
GetAndSetUVs();
}
}
public void GetAndSetUVs()
{
if (!GetRendererReferencesIfNeeded()) return;
if (!isUI)
{
Sprite sprite = spriteRender.sprite;
Rect r = sprite.textureRect;
r.x /= sprite.texture.width;
r.width /= sprite.texture.width;
r.y /= sprite.texture.height;
r.height /= sprite.texture.height;
if(useMaterialInstanceIfPossible && Application.isPlaying)
{
render.material.SetFloat(minXuv, r.xMin);
render.material.SetFloat(maxXuv, r.xMax);
render.material.SetFloat(minYuv, r.yMin);
render.material.SetFloat(maxYuv, r.yMax);
}
else
{
render.sharedMaterial.SetFloat(minXuv, r.xMin);
render.sharedMaterial.SetFloat(maxXuv, r.xMax);
render.sharedMaterial.SetFloat(minYuv, r.yMin);
render.sharedMaterial.SetFloat(maxYuv, r.yMax);
}
}
else
{
Rect r = uiImage.sprite.textureRect;
r.x /= uiImage.sprite.texture.width;
r.width /= uiImage.sprite.texture.width;
r.y /= uiImage.sprite.texture.height;
r.height /= uiImage.sprite.texture.height;
uiImage.material.SetFloat(minXuv, r.xMin);
uiImage.material.SetFloat(maxXuv, r.xMax);
uiImage.material.SetFloat(minYuv, r.yMin);
uiImage.material.SetFloat(maxYuv, r.yMax);
}
}
public void ResetAtlasUvs()
{
if (!GetRendererReferencesIfNeeded()) return;
if (!isUI)
{
if(useMaterialInstanceIfPossible && Application.isPlaying)
{
render.material.SetFloat(minXuv, 0f);
render.material.SetFloat(maxXuv, 1f);
render.material.SetFloat(minYuv, 0f);
render.material.SetFloat(maxYuv, 1f);
}
else
{
render.sharedMaterial.SetFloat(minXuv, 0f);
render.sharedMaterial.SetFloat(maxXuv, 1f);
render.sharedMaterial.SetFloat(minYuv, 0f);
render.sharedMaterial.SetFloat(maxYuv, 1f);
}
}
else
{
uiImage.material.SetFloat(minXuv, 0f);
uiImage.material.SetFloat(maxXuv, 1f);
uiImage.material.SetFloat(minYuv, 0f);
uiImage.material.SetFloat(maxYuv, 1f);
}
}
public void UpdateEveryFrame(bool everyFrame)
{
updateEveryFrame = everyFrame;
}
private bool GetRendererReferencesIfNeeded()
{
if (spriteRender == null) spriteRender = GetComponent<SpriteRenderer>();
if (spriteRender != null)
{
if (spriteRender.sprite == null)
{
#if UNITY_EDITOR
EditorUtility.DisplayDialog("No sprite found", "The object: " + gameObject.name + ",has Sprite Renderer but no sprite", "Ok");
#endif
DestroyImmediate(this);
return false;
}
if (render == null) render = GetComponent<Renderer>();
isUI = false;
}
else
{
if (uiImage == null)
{
uiImage = GetComponent<Image>();
if (uiImage != null)
{
#if UNITY_EDITOR
Debug.Log("You added the SetAtlasUv component to: " + gameObject.name + " that has a UI Image\n " +
"This SetAtlasUV component will only work properly on UI Images if each Image has a DIFFERENT material instance (See Documentation Sprite Atlases section for more info)");
#endif
}
else
{
#if UNITY_EDITOR
EditorUtility.DisplayDialog("No Renderer or UI Graphic found", "This SetAtlasUV component will now get destroyed", "Ok");
#endif
DestroyImmediate(this);
return false;
}
}
if (render == null) render = GetComponent<Renderer>();
isUI = true;
}
if (spriteRender == null && uiImage == null)
{
#if UNITY_EDITOR
EditorUtility.DisplayDialog("No Renderer or UI Graphic found", "This SetAtlasUV component will now get destroyed", "Ok");
#endif
DestroyImmediate(this);
return false;
}
return true;
}
}
}

View File

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

View File

@@ -0,0 +1,26 @@
using UnityEngine;
namespace AllIn1SpriteShader
{
//This script is made with Unity version 2019 and onward in mind
//If you are in Unity 2018 or previous you probably want to use SetGlobalTimeUnity2018.cs instead
//This script will pass in the Unscaled Time to the shader to animate the effects even when the game is paused
//Set shaders to Scaled Time variant and add this script to an active GameObject to see the results
//Video tutorial about it: https://youtu.be/7_BggIufV-w
[ExecuteInEditMode]
public class SetGlobalTimeNew : MonoBehaviour
{
int globalTime;
void Start()
{
globalTime = Shader.PropertyToID("globalUnscaledTime");
}
void Update()
{
Shader.SetGlobalFloat(globalTime, Time.unscaledTime / 20f);
}
}
}

View File

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

View File

@@ -0,0 +1,26 @@
using UnityEngine;
namespace AllIn1SpriteShader
{
//This script is made with Unity version 2018 and previous ones in mind
//If you are in Unity 2019 or onward you probably want to use SetGlobalTimeNew.cs instead
//This script will pass in the Scaled Time to the shader so the effects stop being animated when the game is paused
//Set shaders to Scaled Time variant and add this script to an active GameObject to see the results
//Video tutorial about it: https://youtu.be/7_BggIufV-w
[ExecuteInEditMode]
public class SetGlobalTimeUnity2018 : MonoBehaviour
{
int globalTime;
void Start()
{
globalTime = Shader.PropertyToID("globalUnscaledTime");
}
void Update()
{
Shader.SetGlobalFloat(globalTime, Time.time / 20f);
}
}
}

View File

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