※この記事は2017年07月01日にqiitaに投稿した内容です。
環境
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
}
}
}