[Add] All in one shader
This commit is contained in:
@@ -0,0 +1,179 @@
|
||||
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 LateUpdate()
|
||||
{
|
||||
if (updateEveryFrame)
|
||||
{
|
||||
GetAndSetUVs();
|
||||
}
|
||||
}
|
||||
|
||||
public bool GetAndSetUVs()
|
||||
{
|
||||
if (!GetRendererReferencesIfNeeded()) return false;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user