環境
Unity5.6.2f1
概要
一枚のテクスチャにアニメーション用のグリッドパターンが含まれていて
別のテクスチャにもキャラ替えや色替え等で同じパターンで配置されている場合を想定しています。
例えば以下のURLのキャラ
http://www.istockphoto.com/jp/search/more-like-this/512553428?mediatype=illustration&excludenudity=true&sort=best
ビルトインシェーダーのダウンロード
・Unityをダウンロードするページにアクセス
・「追加ダウンロード」>「ビルトインシェーダー」でダウンロード
スプライト用シェーダの書き換え
・ダウンロードしたzipを開く
・「DefaultResourcesExtra」に「Sprites-Default.shader」、「Sprites-Diffuse.shader」がある
今回の例は「Sprites-Default.shader」を基本としたもの
・シェーダーファイルを複製し、名前を変える(例:CustomSprite_Default.shader)
・複製したシェーダファイルを開く
・名前定義の部分を変える(例:Shader "Custom/Sprite_Default")
・zip内の「CGIncludes」>「UnitySprites.cginc」を開き、以下の部分をシェーダの最後に追加する
sampler2D _MainTex;
sampler2D _AlphaTex;
fixed4 SampleSpriteTexture (float2 uv)
{
fixed4 color = tex2D (_MainTex, uv);
#if ETC1_EXTERNAL_ALPHA
fixed4 alpha = tex2D (_AlphaTex, uv);
color.a = lerp (color.a, alpha.r, _EnableExternalAlpha);
#endif
return color;
}
fixed4 SpriteFrag(v2f IN) : SV_Target
{
fixed4 c = SampleSpriteTexture (IN.texcoord) * IN.color;
c.rgb *= c.a;
return c;
}
・「sampler2D _AlphaTex;」の部分を削除
2重定義になってしまう為
・シェーダ内の「_MainTex」を別の名前に変更する(例:_MainTex2)
Animationが_MainTexにSetTexture()してくる為
・「SampleSpriteTexture」と「SpriteFrag」関数を別の名前に変更する
(例:CustomSampleSpriteTexture、CustomSpriteFrag)
・改名したフラグメントシェーダが呼び出されるようにする
(例:#pragma fragment CustomSpriteFrag)
関数内で呼び出されている部分も変更する
プログラム
マテリアルを作成し、シェーダを設定したら、SpriteRendererに登録します
あとはSetTexture関数で好きなタイミングで変更します
Assets/TestSpriteChange.cs
using UnityEngine;
using UnityEngine.UI;
[RequireComponent( typeof( SpriteRenderer ) )]
public class TestSpriteChange : MonoBehaviour
{
[SerializeField] private Button _button = null;
[SerializeField] private Texture2D[] _textures = null;
private Material _material = null;
private int _textureIndex = 0;
private void Start()
{
var renderer = GetComponent<SpriteRenderer>();
_material = renderer.material;
_material.SetTexture( "_MainTex2", _textures[ _textureIndex ] );
_button.onClick.AddListener( () =>
{
_textureIndex ^= 1;
_material.SetTexture( "_MainTex2", _textures[ _textureIndex ] );
} );
}
}
Assets/CustomSprite_Default.shader
Shader "Custom/Sprite_Default"
{
Properties
{
[PerRendererData] _MainTex2 ("Sprite Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
[MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
[HideInInspector] _RendererColor ("RendererColor", Color) = (1,1,1,1)
[HideInInspector] _Flip ("Flip", Vector) = (1,1,1,1)
[PerRendererData] _AlphaTex ("External Alpha", 2D) = "white" {}
[PerRendererData] _EnableExternalAlpha ("Enable External Alpha", Float) = 0
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Cull Off
Lighting Off
ZWrite Off
Blend One OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex SpriteVert
#pragma fragment CustomSpriteFrag
#pragma target 2.0
#pragma multi_compile_instancing
#pragma multi_compile _ PIXELSNAP_ON
#pragma multi_compile _ ETC1_EXTERNAL_ALPHA
#include "UnitySprites.cginc"
sampler2D _MainTex2;
fixed4 CustomSampleSpriteTexture (float2 uv)
{
fixed4 color = tex2D (_MainTex2, uv);
#if ETC1_EXTERNAL_ALPHA
fixed4 alpha = tex2D (_AlphaTex, uv);
color.a = lerp (color.a, alpha.r, _EnableExternalAlpha);
#endif
return color;
}
fixed4 CustomSpriteFrag(v2f IN) : SV_Target
{
fixed4 c = CustomSampleSpriteTexture (IN.texcoord) * IN.color;
c.rgb *= c.a;
return c;
}
ENDCG
}
}
}