【Unity】シェーダーを使ってスプライト画像の色を変更する方法
ここでは下の動画のように、1枚のスプライト画像から色違いのキャラを作成する、という処理の実装方法を説明します。

なお、この記事は以下の記事で紹介されているものの実装方法を詳しく説明したものとなっています。
やり方が間違っていたのかも知れませんが、こちらの記事のままだとエラーが出てうまく出来なかったので別でまとめさせていただいています。(スクリプトをアタッチするとエラーが出る)
また、この記事で紹介している方法を使って敵を量産した《SHOGI SHOOTING》というゲームをiOS/Androidでリリースしてます。もしよかったらプレイしてみてください。
- iOS:
https://itunes.apple.com/jp/app/shogi-shooting/id1384355738?l=ja&ls=1&mt=8 - GooglePlay:
https://play.google.com/store/apps/details?id=com.ninoichi.SHOGISHOOTING
環境
- Unity 2017.3.1f1
このページの構成
ポイント
- 手順としては以下のとおりです。
- ① 色を変えたいスプライト画像を表示する。
- ② 色を変えるためのシェーダーを作成する。
- ③ ②で作成したシェーダーを適用するマテリアルを作成する。
- ④ ③で作成したマテリアルをスプライト画像にアタッチする。
- ⑤ マテリアルの値を変更して色を変える。
スプライト画像の表示
始めに、色変更したいスプライト画像をシーンビューにドラッグ&ドロップして表示させておいてください。

シェーダーの作成
「Project」から「Create」-「Shader」-「Standard Surface Shader」を選択してシェーダーを作成します。名前はなんでも良いのですが、ここでは元の記事と合わせて”HsvUI”という名前にしています。

作成した”HsvUI”をダブルクリックして”HsvUI.shader”を開き、以下のスクリプトをペタッと全部貼り付けてください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
Shader "Custom/HsvUI" { Properties { [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {} _Hue ("Hue", Float) = 0 //色相 _Sat ("Saturation", Float) = 1 //彩度 _Val ("Value", Float) = 1 //明度 _Color ("Tint", Color) = (1,1,1,1) _StencilComp ("Stencil Comparison", Float) = 8 _Stencil ("Stencil ID", Float) = 0 _StencilOp ("Stencil Operation", Float) = 0 _StencilWriteMask ("Stencil Write Mask", Float) = 255 _StencilReadMask ("Stencil Read Mask", Float) = 255 _ColorMask ("Color Mask", Float) = 15 [Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0 } SubShader { Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" "CanUseSpriteAtlas"="True" } Stencil { Ref [_Stencil] Comp [_StencilComp] Pass [_StencilOp] ReadMask [_StencilReadMask] WriteMask [_StencilWriteMask] } Cull Off Lighting Off ZWrite Off ZTest [unity_GUIZTestMode] Blend SrcAlpha OneMinusSrcAlpha ColorMask [_ColorMask] Pass { Name "Default" CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma target 2.0 #include "UnityCG.cginc" #include "UnityUI.cginc" #pragma multi_compile __ UNITY_UI_CLIP_RECT #pragma multi_compile __ UNITY_UI_ALPHACLIP struct appdata_t { float4 vertex : POSITION; float4 color : COLOR; float2 texcoord : TEXCOORD0; UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : SV_POSITION; fixed4 color : COLOR; float2 texcoord : TEXCOORD0; float4 worldPosition : TEXCOORD1; UNITY_VERTEX_OUTPUT_STEREO }; fixed4 _Color; fixed4 _TextureSampleAdd; float4 _ClipRect; half _Hue, _Sat, _Val; fixed3 shift_col(fixed3 RGB, half3 shift) { fixed3 RESULT = fixed3(RGB); float VSU = shift.z*shift.y*cos(shift.x*3.14159265/180); float VSW = shift.z*shift.y*sin(shift.x*3.14159265/180); RESULT.x = (.299*shift.z+.701*VSU+.168*VSW)*RGB.x + (.587*shift.z-.587*VSU+.330*VSW)*RGB.y + (.114*shift.z-.114*VSU-.497*VSW)*RGB.z; RESULT.y = (.299*shift.z-.299*VSU-.328*VSW)*RGB.x + (.587*shift.z+.413*VSU+.035*VSW)*RGB.y + (.114*shift.z-.114*VSU+.292*VSW)*RGB.z; RESULT.z = (.299*shift.z-.3*VSU+1.25*VSW)*RGB.x + (.587*shift.z-.588*VSU-1.05*VSW)*RGB.y + (.114*shift.z+.886*VSU-.203*VSW)*RGB.z; return (RESULT); } v2f vert(appdata_t v) { v2f OUT; UNITY_SETUP_INSTANCE_ID(v); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT); OUT.worldPosition = v.vertex; OUT.vertex = UnityObjectToClipPos(OUT.worldPosition); OUT.texcoord = v.texcoord; OUT.color = v.color * _Color; return OUT; } sampler2D _MainTex; fixed4 frag(v2f IN) : SV_Target { half4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color; #ifdef UNITY_UI_CLIP_RECT color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect); #endif #ifdef UNITY_UI_ALPHACLIP clip (color.a - 0.001); #endif half3 shift = half3(_Hue, _Sat, _Val); return fixed4( shift_col(color, shift), color.a); } ENDCG } } } |
シェーダーの作成は以上で終了です。
記事の冒頭でも書きましたが、こちらのスクリプトは以下の記事のものをそのまま使用させていただいています。ありがとうございます。
マテリアルの作成
次にマテリアルを作成します。「Project」から「Create」-「Material」を選択してください。
これも名前はなんでも良いのですが、ここでは”M_ChangeColor”という名前にしています。

このマテリアルに先ほど作成したシェーダーを適用します。
作成したマテリアルを選択し、「inspector」から「Shader」-「Custom」-「HsvUI」を選択してください。(HsvUIのところはシェーダー作成時につけた名前が表示されるので、違う名称になっているかも知れません)

最後に、スプライトにこのマテリアルを適用します。
スプライトを選択し、「inspector」から「Sprite Renderer」-「Material」に先ほど作成したマテリアルをドラッグ&ドロップしてください。

以上で準備は完了です!
色の変更
スプライトの「inspector」から「M_ChangeColor」の「Hue」「Saturation」「Value」あたりの値を変えてみてください。スプライト画像の色が変更されると思います。(Hueは色相、Saturationは彩度、Valueは明度の値です)
