【Unity】2D Sprite九宫格(NineSliced)

来源:互联网 发布:java基础入门课后答案 编辑:程序博客网 时间:2024/05/16 15:07

支持新的2D系统的Unity会在2017年发布,届时会发布九宫格,TileMap等强大的2D特性,不过现在能用的只是alpha版而已,很多功能做得还不够好,接口也不完善,实际开发也比较鸡肋,所以自己写了一个2D九宫格,具体逻辑什么的有空再写
这里写图片描述

这里写图片描述

这里写图片描述

C#代码:

/**Author: 邵志恒*Blog: http://blog.csdn.net/rickshaozhiheng/article/details/53608168*Email: zhiheng.rick@gmail.com*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代码:

/**Author: 邵志恒*Blog: http://blog.csdn.net/rickshaozhiheng/article/details/53608168*Email: zhiheng.rick@gmail.com*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        }    }}
0 0