Unity 2D Sprite九宫格(NineSliced)
发表于2018-04-17
Unity在2017年支持新的2D系统,有九宫格、TileMap等强大的2D特性,考虑到有些人还不熟悉,下面就和大家介绍下2D Sprite九宫格开发。
C#代码:
*Shader修改自unity5.5.0内置shader * set Image Import Setting ->MeshType to Full Rect */ using System.Collections; using System.Collections.Generic; using UnityEngine; [DisallowMultipleComponent] [ExecuteInEditMode] [RequireComponent(typeof(SpriteRenderer))] public class NineSlicedProvider : MonoBehaviour { public bool refreshEveryFrame = false; SpriteRenderer m_SpriteRenderer; SpriteRenderer spriteRenderer { get{ if (m_SpriteRenderer == null) { m_SpriteRenderer = this.GetComponent<SpriteRenderer> (); } return m_SpriteRenderer; } } Material m_Material; Material material { get{ if (spriteRenderer == null) { m_Material = null; return null; } if (m_Material == null) { spriteRenderer.sharedMaterial = new Material(Shader.Find("Rickshao/NineSlicedShader")); m_Material = spriteRenderer.sharedMaterial; } return m_Material; } } void OnEnable() { SetShaderVaries (); } // Update is called once per frame void Update () { if (refreshEveryFrame) { SetShaderVaries(); } } void SetShaderVaries() { if (spriteRenderer == null || spriteRenderer.sprite == null) return; float width = spriteRenderer.sprite.rect.width; float height = spriteRenderer.sprite.rect.height; float borderLeft = spriteRenderer.sprite.border.x; float borderBottom = spriteRenderer.sprite.border.y; float borderRight = spriteRenderer.sprite.border.z; float borderTop = spriteRenderer.sprite.border.w; float left = borderLeft / width; float bottom = borderBottom / height; float right = borderRight / width; float top = borderTop / height; //Debug.Log ("top " + top + " bottom " + bottom + " left " + left + " right " + right); material.SetFloat("top", top); material.SetFloat("bottom", bottom); material.SetFloat("right", right); material.SetFloat("left", left); material.SetFloat("sx", this.transform.localScale.x); material.SetFloat ("sy", this.transform.localScale.y); } }
Shader代码:
*Shader修改自unity5.5.0内置shader * set Image Import Setting ->MeshType to Full Rect */ Shader "Rickshao/NineSlicedShader" { Properties { [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {} [HideInInspector]_Color ("Tint", Color) = (1,1,1,1) [HideInInspector][MaterialToggle] PixelSnap ("Pixel snap", 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 vert #pragma fragment frag #pragma target 2.0 #pragma multi_compile _ PIXELSNAP_ON #pragma multi_compile _ ETC1_EXTERNAL_ALPHA #include "UnityCG.cginc" float top; float bottom; float left; float right; float sx; float sy; struct appdata_t { float4 vertex : POSITION; float4 color : COLOR; float2 texcoord : TEXCOORD0; //UNITY_VERTEX_INPUT_INSTANCE_ID //copied from 5.5, not work in 5.4 }; struct v2f { float4 vertex : SV_POSITION; fixed4 color : COLOR; float2 texcoord : TEXCOORD0; //UNITY_VERTEX_OUTPUT_STEREO }; fixed4 _Color; float2 UVTransform(float2 origin) { float2 result = origin; if(left + right > sx) { result.x = origin.x; } else { if (origin.x * sx < left) { result.x = origin.x * sx; } else { if ((1 - origin.x) * sx < right) { result.x = 1 - (1 - origin.x) * sx; } else { result.x = (origin.x * sx - left) / (sx - left - right)*(1 - left - right) + left; } } } if (top + bottom > sy) { result.y = origin.y; }else { if (origin.y * sy < top) { result.y = origin.y * sy; } else { if ((1 - origin.y) * sy < bottom) { result.y = 1 - (1 - origin.y) * sy; } else { result.y = (origin.y * sy - top) / (sy - top - bottom)*(1 - top - bottom) + top; } } } return result; } v2f vert(appdata_t IN) { v2f OUT; UNITY_SETUP_INSTANCE_ID(IN); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT); OUT.vertex = UnityObjectToClipPos(IN.vertex); OUT.texcoord = IN.texcoord; OUT.color = IN.color * _Color; #ifdef PIXELSNAP_ON OUT.vertex = UnityPixelSnap (OUT.vertex); #endif return OUT; } sampler2D _MainTex; sampler2D _AlphaTex; fixed4 SampleSpriteTexture (float2 uv) { fixed4 color = tex2D (_MainTex, uv); #if ETC1_EXTERNAL_ALPHA // get the color from an external texture (usecase: Alpha support for ETC1 on android) color.a = tex2D (_AlphaTex, uv).r; #endif //ETC1_EXTERNAL_ALPHA return color; } fixed4 frag(v2f IN) : SV_Target { fixed4 c = SampleSpriteTexture (UVTransform(IN.texcoord)) * IN.color; c.rgb *= c.a; return c; } ENDCG } } }
来自:https://blog.csdn.net/rickshaozhiheng/article/details/53608168