Sprite Flipping Without using LocalScale

Didn’t like flipping sprites by inverting the localscale, so decided to write a texture flipping editor extension.

However that didn’t work with animations/spritesheets, next I decided to try and flip the sprite on a shader level.

Which works although currently you have to set the spritesheet width, the individual sprites width for the shader to work ( didn’t know how to access those values from within the shader ).

Anyway The code for the editor extension and shader are bellow, all this to avoid localscale messing with the rotations.

using UnityEngine;
using System.Collections;
using System.IO;
using UnityEditor;

public class flipImage : ScriptableWizard {
    public Texture2D[] inputTexture = new Texture2D[1];
    public string filenameInsert="-flipped";
    private Texture2D outputTexture;
    private Color[] textureData;
    private Color[] outputData;

    // Use this for initialization
    [MenuItem("Window/Flip Texture")]
    public static void ShowWindow()
    {
        ScriptableWizard.DisplayWizard("Flip Texture(s)", typeof(flipImage), "Flip Texture(s)");
    }

    void OnWizardCreate()
    {

        for(int d=0; d<inputTexture.Length;d++)
        {
            // Get Texture data
            textureData = inputTexture[d].GetPixels();
            outputData = new Color[textureData.Length];

            // Flip the Texture
            for(int y=0; y< inputTexture[d].height; y++)
            {
                for(int x=inputTexture[d].width-1; x > 1; x--)
                {
                    outputData[((y*inputTexture[d].width)+(inputTexture[d].width-x))]=textureData[((y*inputTexture[d].width)+x)];
                }
            }

            // Write to a new Texture
            outputTexture =  new Texture2D(inputTexture[d].width, inputTexture[d].height, inputTexture[d].format,false);
            outputTexture.SetPixels(outputData);
            outputTexture.Apply();
            byte[] bytes = outputTexture.EncodeToPNG();
            string infile=AssetDatabase.GetAssetPath(inputTexture[d]);
            string outfile=infile.Insert(infile.Length-4,filenameInsert);
            File.WriteAllBytes(outfile, bytes);
        }

        AssetDatabase.Refresh();

    }
}

And the shader, which works with animationed sprites/spritesheets.

Shader "Sprites/Flippable"
{
    Properties
    {
        [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
        _Color ("Tint", Color) = (1,1,1,1)
        _Alpha ("Alpha", float) = 1
        [MaterialToggle] _Flip ("Flip", Float) = 0
        _SheetWidth ("SheetWidth", float) = 0
        _SpriteWidth ("SpriteWidth", float) = 0
        [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
    }

    SubShader
    {
        Tags
        {
            "Queue"="Transparent"
            "IgnoreProjector"="True"
            "RenderType"="Transparent"
            "PreviewType"="Plane"
            "CanUseSpriteAtlas"="True"
        }

        Cull Off
        Lighting Off
        ZWrite Off
        Fog { Mode Off }
        Blend One OneMinusSrcAlpha

        Pass
        {
        CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile DUMMY PIXELSNAP_ON
            #include "UnityCG.cginc"
         
            struct appdata_t
            {
                float4 vertex   : POSITION;
                float4 color    : COLOR;
                float2 texcoord : TEXCOORD0;
            };

            struct v2f
            {
                float4 vertex   : SV_POSITION;
                fixed4 color    : COLOR;
                half2 texcoord  : TEXCOORD0;
            };
         
            sampler2D _MainTex;
            fixed4 _Color;
            float _Alpha;
            float _SheetWidth;
            float _SpriteWidth;
            float _Flip;

            v2f vert(appdata_t IN)
            {
                v2f OUT;
                OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex);
                OUT.texcoord = IN.texcoord;
             
               if ( _Flip != 0.0 )
               {
                    int column=((IN.texcoord.x*_SheetWidth)+_SpriteWidth)/_SpriteWidth;
                    OUT.texcoord.x = ((((1.0/_SheetWidth)*_SpriteWidth)*(column+1))-IN.texcoord.x);
                }
                 
                OUT.color = IN.color * _Color;
                OUT.color.a = OUT.color.a * _Alpha;
                #ifdef PIXELSNAP_ON
                OUT.vertex = UnityPixelSnap (OUT.vertex);
                #endif

                return OUT;
            }



            fixed4 frag(v2f IN) : SV_Target
            {
                fixed4 c = tex2D(_MainTex, IN.texcoord) * IN.color;
                c.rgb *= c.a;
             
                return c;
            }
        ENDCG
        }
    }
}

Getting a little flicker with animations using the shader, working on fixing it

EDIT: Still no solution, getting weird results when animations are playing it renders a sprite from a completely different row…