项目demo之——翻页

先上图 看效果

分析:

1.分页由shader实现

2.shader的图片类容由截屏功能实现

3.按钮触发功能

有2个cs文件 1个shader组成

代码如下

1.EventTriggerListener.cs //将此代码放在项目中任何地方

using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
public class EventTriggerListener : UnityEngine.EventSystems.EventTrigger
{
    public delegate void VoidDelegate(GameObject go);
    public VoidDelegate onClick;
    public VoidDelegate onDown;
    public VoidDelegate onEnter;
    public VoidDelegate onExit;
    public VoidDelegate onUp;
    public VoidDelegate onSelect;
    public VoidDelegate onUpdateSelect;

    static public EventTriggerListener Get(GameObject go)
    {
        EventTriggerListener listener = go.GetComponent<EventTriggerListener>();
        if (listener == null) listener = go.AddComponent<EventTriggerListener>();
        return listener;
    }
    public override void OnPointerClick(PointerEventData eventData)
    {
        if (onClick != null) onClick(gameObject);
    }
    public override void OnPointerDown(PointerEventData eventData)
    {
        if (onDown != null) onDown(gameObject);
    }
    public override void OnPointerEnter(PointerEventData eventData)
    {
        if (onEnter != null) onEnter(gameObject);
    }
    public override void OnPointerExit(PointerEventData eventData)
    {
        if (onExit != null) onExit(gameObject);
    }
    public override void OnPointerUp(PointerEventData eventData)
    {
        if (onUp != null) onUp(gameObject);
    }
    public override void OnSelect(BaseEventData eventData)
    {
        if (onSelect != null) onSelect(gameObject);
    }
    public override void OnUpdateSelected(BaseEventData eventData)
    {
        if (onUpdateSelect != null) onUpdateSelect(gameObject);
    }
}

2.UIMain.cs //将此代码拖到按钮上

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using UnityEngine.Events;
public class UIMain : MonoBehaviour
{
    Button button;
    //接屏文件的大小
    Rect r = new Rect(0, 0, 1136, 640);
    //截屏出来的图片
    Texture m_Texture;
    //得到书的renderer组件
    Renderer m_Renderer;
    //控制shader开关的数值
    [Range(0, 1)]
    float time = 0f;
    //翻页的布尔值,控制updata里的翻页触发
    bool flip = false;
    //翻了第几页
    int numberOfpages = 0;
    //书页目录的物体
    Transform book_Catalog;
    //书页目录物体的缩放值
    Vector3 bookBack;


    //各个程序功能的页面
    Transform parent01;
    Transform parent02;
    Transform parent03;
    Transform parent04;
    Transform parent05;
    Transform parent06;
    Transform parent07;
    Transform parent08;





    void Start()
    {
        book_Catalog = GameObject.Find("book_beimian").GetComponent<Transform>();
        m_Renderer = GameObject.Find("Object001").GetComponent<Renderer>();
        bookBack = book_Catalog.localScale;

        button = transform.Find("Button").GetComponent<Button>();
        EventTriggerListener.Get(button.gameObject).onClick = OnButtonClick;

        //程序页面的实例化
        parent01 = GameObject.Find("1").GetComponent<Transform>();
        parent02 = GameObject.Find("2").GetComponent<Transform>();
        parent03 = GameObject.Find("3").GetComponent<Transform>();
        parent04 = GameObject.Find("4").GetComponent<Transform>();
        parent05 = GameObject.Find("5").GetComponent<Transform>();
        parent06 = GameObject.Find("6").GetComponent<Transform>();
        parent07 = GameObject.Find("7").GetComponent<Transform>();
        parent08 = GameObject.Find("8").GetComponent<Transform>();
        
    }

    private void OnButtonClick(GameObject go)
    {
        //在这里监听按钮的点击事件
        if (go == button.gameObject)
        {
            if(time ==0)
            {
                //Debug.Log("DoSomeThings");
                //记录页面
                pages();
                //得到截屏的图片
                m_Texture = CaptureScreen(Camera.main, r);
                //将截屏图片赋值给book
                m_Renderer.material.SetTexture("_MainTex", m_Texture);
                //设置翻页为正
                flip = true;

               

            }

        }
    }

   

    //截屏 返回截屏图片
    public Texture2D CaptureScreen(Camera c, Rect r)
    {
        RenderTexture rt = new RenderTexture((int)r.width, (int)r.height, 0);

        c.targetTexture = rt;
        c.Render();

        RenderTexture.active = rt;
        Texture2D screenShot = new Texture2D((int)r.width, (int)r.height, TextureFormat.RGB24, false);
        screenShot.ReadPixels(r, 0, 0);
        screenShot.Apply();

        c.targetTexture = null;
        RenderTexture.active = null;
        GameObject.Destroy(rt);

        //byte[] bytes = screenShot.EncodeToPNG();
        //string filename = Application.dataPath + "/ScreenShot.png";
        //System.IO.File.WriteAllBytes(filename, bytes);

        return screenShot;
    }


    

    void Update()
    {
        //得到书目录的物体缩放值 
        Vector3 s = book_Catalog.localScale;

        if (time >= 1)
        {
            //当翻页完成的时候,将其放大到原来大小
            if (s.x <= bookBack.x && s.y <= bookBack.y)
            {
                s.x += Time.deltaTime;
                s.y += Time.deltaTime;
                book_Catalog.localScale = s;
            }
                
            //将翻页设置为假
            flip = false;
            //当目录缩放到原来大小的时候,将shader中的翻页设置为0
            if (s.x >= bookBack.x && s.y >= bookBack.y)
            time = 0;
            
        }


        if (flip)
        {
            //如果翻页为正的是后
            //将目录缩小到0大小
            if (s.x >= 0 && s.y >= 0)
            {
                s.x -= Time.deltaTime;
                s.y -= Time.deltaTime;
                book_Catalog.localScale = s;
            }
                

            //然后再开始翻页
            time = time + Time.deltaTime;
            //及时将翻页的进度传递给shader
            m_Renderer.material.SetFloat("_time01", time);
            //开始翻页的时候 切换程序页面
            if (time > 0.1)
            {

                if (numberOfpages == 0)
                {
                    yemian(parent08, parent01);
                }
                if (numberOfpages == 1)
                {
                    yemian(parent01, parent02);
                }
                if (numberOfpages == 2)
                {
                    yemian(parent02, parent03);
                }
                if (numberOfpages == 3)
                {
                    yemian(parent03, parent04);
                }
                if (numberOfpages == 4)
                {
                    yemian(parent04, parent05);
                }
                if (numberOfpages == 5)
                {
                    yemian(parent05, parent06);
                }
                if (numberOfpages == 6)
                {
                    yemian(parent06, parent07);
                }
                if (numberOfpages == 7)
                {
                    yemian(parent07, parent08);
                }

            }

        }
        
       

    }

    //记录翻页的页数,每反一页,会+1,+到8的时候 让他从0开始循环
   public void pages() {
        numberOfpages++;
        if (numberOfpages == 8)
        {
            numberOfpages = 0;
        }

        
    }

    //消失上一页 出现下一页,在update里通过页数来确定上一页与下一页
    //输入上一页跟下一页 
    public void yemian(Transform a,Transform b)
    {
        //上一页消失
        Renderer[] child_a = a.GetComponentsInChildren<Renderer>();
        for (int i = 0; i < child_a.Length; i++)
        {
            if (time>=0.2)
            child_a[i].enabled = false;

        }

        //下一页出现
        Renderer[] child_b = b.GetComponentsInChildren<Renderer>();
        for (int i = 0; i < child_b.Length; i++)
        {
            if (time >= 0.2)
                child_b[i].enabled = true;
        }
    }

}

3.Book.shader

Shader "Unlit/Book"
{
    Properties
    {    
        //主贴图,来自截图的贴图
        _MainTex ("Texture", 2D) = "white" {}
        //反面贴图
        _BackTex ("BackTex",2D) = "white"{}
        //翻页的过程
        _time01 ("time01",Range(0,1)) = 0
        //以uv为中点,调节bookuv大小,来配合截图的贴图
        _tilingX ("tilingX",range(0.95,1.05)) = 1
        _tilingY ("tilingY",range(0.95,1.05)) = 1
        _OffsetX ("OffsetX",range(-0.02,0.02)) = 0
        _OffsetY ("OffsetY",range(-0.02,0.02)) = 0

    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

            CGINCLUDE
            #include "UnityCG.cginc"
            #define pi 3.1415926
            sampler2D _MainTex;
            sampler2D _BackTex;
            float4 _MainTex_ST;
            float _time01;
            float _tilingX;
            float _tilingY;
            float _OffsetX;
            float _OffsetY;

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            //翻页的顶点着色器
            v2f vert_flip (appdata v)
            {    
                float4 vert = v.vertex;
                float theta =  _time01 * pi;
                float flipCurve = exp(-0.1 * pow(v.vertex.x - 0.5, 2)) * _time01;
                theta +=flipCurve;

                vert.x = v.vertex.x * cos(clamp (theta,0,pi));
                vert.y = -v.vertex.x * sin(clamp (theta,0,pi))+0.01;
                v2f o;                
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                vert = o.uv.x<=0.5 ? v.vertex:vert;
                o.vertex = UnityObjectToClipPos(vert);
                return o;
            }
            //第二页顶点着色器,跟翻页的背面公用
            v2f vert_Nex (appdata v) 
            {
                float4 vert = v.vertex;
                v2f o;                
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                o.uv.y =  o.uv.y;
                o.vertex = UnityObjectToClipPos(v.vertex);
                return o;
            }

            //翻页的片段
            fixed4 frag_flip (v2f i) : SV_Target
            {
                i.uv = float2 ((i.uv.x -0.5)* _tilingX +0.5,(i.uv.y-0.5) * _tilingY +0.5 );
                i.uv += float2(_OffsetX,_OffsetY);
                fixed4 col = tex2D(_MainTex, i.uv);
                return col;
            }

            //翻页的背面片段
            fixed4 frag_Back (v2f i ) : sv_target
            {
                i.uv.x = 1 - i.uv.x;
                i.uv = float2 ((i.uv.x -0.5)* _tilingX +0.5,(i.uv.y-0.5) * _tilingY +0.5 );
                i.uv += float2(_OffsetX,_OffsetY);

                fixed4 col = tex2D(_BackTex,i.uv);
                return col;
            }

            //第二页的片段
            fixed4 frag_Next (v2f i ) : sv_target
            {
                i.uv.x = i.uv.x;
                i.uv = float2 ((i.uv.x -0.5)* _tilingX +0.5,(i.uv.y-0.5) * _tilingY +0.5 );
                i.uv += float2(_OffsetX,_OffsetY);

                fixed4 col = tex2D(_BackTex,i.uv);
                return col;
            }
            ENDCG

        //第一个pass 翻页
        Pass
        {
            Cull Back
            Offset 0, 0
            CGPROGRAM
            #pragma vertex vert_flip
            #pragma fragment frag_flip
            ENDCG
        }

        //第二个pass 翻页的背面
        Pass
        {
            Cull Front 
            Offset -1, -1
            CGPROGRAM
            #pragma vertex vert_flip
            #pragma fragment frag_Back
            ENDCG
        }
        //第三个pass 第二页
        Pass
        {
            Cull Back 
            Offset 1, 1
            CGPROGRAM
            #pragma vertex vert_Nex
            #pragma fragment frag_Next
            ENDCG
        }

    }
}

项目资源如下:

链接:http://pan.baidu.com/s/1eS1YSrK 密码:j0qu

 

posted @ 2017-11-03 13:41  欧恩Owen  阅读(280)  评论(0编辑  收藏  举报