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
}
}
}