unity Book-Page Curl

既能翻页又能点击

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Controll : MonoBehaviour
{

    public static int currentPage;
    public AutoFlip _autoFlip;
    // Start is called before the first frame update
    void Start()
    {
        
    }

    private bool isClick;
    private int _index;
    public void OnClickNameButton(int index)
    {
        isClick = true;
        _index = index;
        isDelay = true;
        //for (int i = 0; i < mediaPlayers.Length; i++)
        //{
        //    //mediaPlayers[i].Pause();
        //    mediaPlayers[i].Rewind(true);
        //}
    }

    private float count;
    private bool isDelay;
    // Update is called once per frame
    void Update()
    {
        if (isClick)
        {
            if (_index != currentPage)
            {
                if (isDelay)
                {
                    if (_index < currentPage)
                    {
                        _autoFlip.FlipLeftPage();
                    }
                    if (_index > currentPage)
                    {
                        _autoFlip.FlipRightPage();
                    }
                    isDelay = false;
                }
                if (count < 1)
                {
                    count += Time.deltaTime;
                }
                else
                {
                    count = 0;
                    isDelay = true;
                }
                //for (int i = 0; i < mediaPlayers.Length; i++)
                //{
                //    mediaPlayers[i].Rewind(true);
                //}
            }
            else
            {
                isClick = false;
            }

        }
    }
}

 翻书的时间控制:

直接跳转到某一页(没有翻页的动画):

修改翻页区域:

 修改小幅度滑动就能翻页:

修改直接点击可以看到翻页动画的:

 

 

public void DragRightPageToPoint(Vector3 point,bool isClick=false,int count=1)
    {
        if (currentPaper > EndFlippingPaper) return;
        pageDragging = true;
        mode = FlipMode.RightToLeft;
        f = point;

        ClippingPlane.rectTransform.pivot = new Vector2(1, 0.35f);
        //Debug.Log("currentPaper: " + currentPaper);
        for (int i = 0; i < papers.Length; i++)
        {
            papers[i].Front.GetComponent<Image>().gameObject.SetActive(true);
            papers[i].Back.GetComponent<Image>().gameObject.SetActive(true);
        }
        currentPaper += count;
        for (int i = 1; i <count; i++) // 8 6 4  i:1 2 3
        {
            papers[currentPaper - i].Front.GetComponent<Image>().gameObject.SetActive(false);
        }
        //UpdatePages();

        Left = papers[currentPaper - count].Front.GetComponent<Image>();
        //Debug.Log("Left: " + Left.name);//滑动的那个
        BookUtility.ShowPage(Left.gameObject);
        Left.rectTransform.pivot = new Vector2(0, 0);
        Left.transform.position = RightPageTransform.transform.position;
        Left.transform.localEulerAngles = new Vector3(0, 0, 0);

        for (int i = 2; i <= count; i++) //
        {
            papers[currentPaper - i].Back.GetComponent<Image>().gameObject.SetActive(false);
            //Debug.Log("papers[currentPaper - i].Back: " + papers[currentPaper - i].Back.name);
        }
        Right = papers[currentPaper - 1].Back.GetComponent<Image>();
        //Debug.Log("Right: " + Right.name);
        BookUtility.ShowPage(Right.gameObject);
        Right.transform.position = RightPageTransform.transform.position;
        Right.transform.localEulerAngles = new Vector3(0, 0, 0);
        
        if (enableShadowEffect) Shadow.gameObject.SetActive(true);
        ClippingPlane.gameObject.SetActive(true);
        Controll._delay = true;//翻页角好像翻了两遍,效果不大
        UpdateBookRTLToPoint(f);
        
    }

 public void DragLeftPageToPoint(Vector3 point,bool isClick = false, int count = 1)
    {
        if (currentPaper <= StartFlippingPaper) return;
        pageDragging = true;
        mode = FlipMode.LeftToRight;
        f = point;
        if (isClick)
        {
            currentPaper -= count;
           // UpdatePages();
        }

        for (int i = 0; i < papers.Length; i++)
        {
            papers[i].Front.GetComponent<Image>().gameObject.SetActive(true);
            papers[i].Back.GetComponent<Image>().gameObject.SetActive(true);
        }
        ClippingPlane.rectTransform.pivot = new Vector2(0, 0.35f);

        if (isClick )
        {
            Debug.Log("currentPaper+ count: "+ (currentPaper + count));
            for (int i = currentPaper; i < currentPaper + count-1; i++)
            {
                papers[i].Back.GetComponent<Image>().gameObject.SetActive(false);
            }
            Right = papers[currentPaper+count-1].Back.GetComponent<Image>();
        }
        else
        {
            Right = papers[currentPaper-1].Back.GetComponent<Image>();
        }
        Debug.Log("Right name: " + papers[currentPaper - 1].Back.name);
        BookUtility.ShowPage(Right.gameObject);
        Right.transform.position = LeftPageTransform.transform.position;
        Right.transform.localEulerAngles = new Vector3(0, 0, 0);
        Right.transform.SetAsFirstSibling();

        if (isClick)
        {            
            Left = papers[currentPaper].Front.GetComponent<Image>();            
        }
        else
        {
            Left = papers[currentPaper-1].Front.GetComponent<Image>();
        }
        //Debug.Log("Left name: " + papers[currentPaper - 1].Front.name);
        BookUtility.ShowPage(Left.gameObject);
        Left.gameObject.SetActive(true);
        Left.rectTransform.pivot = new Vector2(1, 0);
        Left.transform.position = LeftPageTransform.transform.position;
        Left.transform.localEulerAngles = new Vector3(0, 0, 0);


        if (enableShadowEffect) ShadowLTR.gameObject.SetActive(true);
        ClippingPlane.gameObject.SetActive(true);
        Controll._delay = true;//翻页角好像翻了两遍,效果不大
        UpdateBookLTRToPoint(f);
       
    }

 

 

总结:点击翻到指定页的过程,效果还不是很好。

将脚本整合到一个脚本里:

using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using System.Collections;
using System;
using System.Collections.Generic;

public enum FlipMode
{
    RightToLeft,
    LeftToRight
}
public class BookPro : MonoBehaviour
{
    Canvas canvas;
    [SerializeField]
    RectTransform BookPanel;
    public Image ClippingPlane;
    public Image Shadow;
    public Image LeftPageShadow;
    public Image RightPageShadow;
    public Image ShadowLTR;
    public RectTransform LeftPageTransform;
    public RectTransform RightPageTransform;
    public bool interactable = true;
    public bool enableShadowEffect = true;
    [Tooltip("Uncheck this if the book does not contain transparent pages to improve the overall performance")]
    public bool hasTransparentPages = true;
    [HideInInspector]
    public int currentPaper = 0;
    [HideInInspector]
    public Paper[] papers;

    private List<Image> letfFlipPages = new List<Image>();
    private List<Image> rightFlipPages = new List<Image>();
    /// <summary>
    /// OnFlip invocation list, called when any page flipped
    /// </summary>
    public UnityEvent OnFlip;

    /// <summary>
    /// The Current Shown paper (the paper its front shown in right part)
    /// </summary>
    public int CurrentPaper
    {
        get { return currentPaper; }
        set
        {
            if (value != currentPaper)
            {
                if (value <StartFlippingPaper)
                    currentPaper = StartFlippingPaper;
                else if (value > EndFlippingPaper+1)
                    currentPaper = EndFlippingPaper+1;
                else
                    currentPaper = value;
                UpdatePages();
            }
        }
    }
    [HideInInspector]
    public int StartFlippingPaper = 0;
    [HideInInspector]
    public int EndFlippingPaper = 1;

    public Vector3 EndBottomLeft
    {
        get { return ebl; }
    }
    public Vector3 EndBottomRight
    {
        get { return ebr; }
    }
    public float Height
    {
        get
        {
            return BookPanel.rect.height;
        }
    }

    Image Left;
    Image Right;

    //current flip mode
    FlipMode mode;

    /// <summary>
    /// this value should e true while the user darg the page
    /// </summary>
    bool pageDragging = false;

    /// <summary>
    /// should be true when the page tween forward or backward after release
    /// </summary>
    bool tweening = false; 

    // Use this for initialization
    void Start()
    {
        Canvas[] c = GetComponentsInParent<Canvas>();
        if (c.Length > 0)
            canvas = c[c.Length - 1];
        else
            Debug.LogError("Book Must be a child to canvas diectly or indirectly");

        UpdatePages();
        //Debug.Log("papers[currentPaper].Front: " + papers[currentPaper].Front.name);
        //Debug.Log("papers[currentPaper].Back: " + papers[currentPaper].Back.name);
        Controll.currentPage = currentPaper;
        CalcCurlCriticalPoints();

        //Debug.Log("BookPanel: " + BookPanel.name);
        float pageWidth = BookPanel.rect.width / 2.0f; //书页的宽度
        float pageHeight = BookPanel.rect.height;//书页的高度


        ClippingPlane.rectTransform.sizeDelta = new Vector2(pageWidth * 2 + pageHeight, pageHeight + pageHeight * 2);

        //hypotenous (diagonal) page length
        float hyp = Mathf.Sqrt(pageWidth * pageWidth + pageHeight * pageHeight);
        float shadowPageHeight = pageWidth / 2 + hyp;

        Shadow.rectTransform.sizeDelta = new Vector2(pageWidth, shadowPageHeight);
        Shadow.rectTransform.pivot = new Vector2(1, (pageWidth / 2) / shadowPageHeight);

        ShadowLTR.rectTransform.sizeDelta = new Vector2(pageWidth, shadowPageHeight);
        ShadowLTR.rectTransform.pivot = new Vector2(0, (pageWidth / 2) / shadowPageHeight);

        RightPageShadow.rectTransform.sizeDelta = new Vector2(pageWidth, shadowPageHeight);
        RightPageShadow.rectTransform.pivot = new Vector2(0, (pageWidth / 2) / shadowPageHeight);

        LeftPageShadow.rectTransform.sizeDelta = new Vector2(pageWidth, shadowPageHeight);
        LeftPageShadow.rectTransform.pivot = new Vector2(1, (pageWidth / 2) / shadowPageHeight);
    }

    /// <summary>
    /// transform point from global (world-space) to local space
    /// </summary>
    /// <param name="global">poit iin world space</param>
    /// <returns></returns>
    public Vector3 transformPoint(Vector3 global)
    {
        Vector2 localPos = BookPanel.InverseTransformPoint(global);
        return localPos;
    }
    /// <summary>
    /// transform mouse position to local space
    /// </summary>
    /// <param name="mouseScreenPos"></param>
    /// <returns></returns>
    public Vector3 transformPointMousePosition(Vector3 mouseScreenPos)
    {
        if(canvas.renderMode== RenderMode.ScreenSpaceCamera )
        {
            Vector3 mouseWorldPos = canvas.worldCamera.ScreenToWorldPoint(new Vector3(mouseScreenPos.x, mouseScreenPos.y, canvas.planeDistance));
            Vector2 localPos = BookPanel.InverseTransformPoint(mouseWorldPos);

            return localPos;
        }
        else if ( canvas.renderMode == RenderMode.WorldSpace)
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            Vector3 globalEBR = transform.TransformPoint(ebr);
            Vector3 globalEBL = transform.TransformPoint(ebl);
            Vector3 globalSt = transform.TransformPoint(st);
            Plane p = new Plane(globalEBR, globalEBL, globalSt);
            float distance;
            p.Raycast(ray, out distance);
            Vector2 localPos = BookPanel.InverseTransformPoint(ray.GetPoint(distance));
            return localPos;
        }
        else
        {
            //Screen Space Overlay
            Vector2 localPos = BookPanel.InverseTransformPoint(mouseScreenPos);
            return localPos;
        }
        
    }

    /// <summary>
    /// Update page orders
    /// This function should be called whenever the current page changed, the dragging of the page started or the page has been flipped
    /// </summary>
    public void UpdatePages()
    {
        //Debug.Log("1234567");
        int previousPaper = pageDragging ? currentPaper - 2 : currentPaper - 1;
        //Debug.Log("previousPaper: " + previousPaper);
        //Hide all pages
        for (int i = 0; i < papers.Length; i++)
        {
            BookUtility.HidePage(papers[i].Front);
            papers[i].Front.transform.SetParent(BookPanel.transform);
            BookUtility.HidePage(papers[i].Back);
            papers[i].Back.transform.SetParent(BookPanel.transform);
        }

        if (hasTransparentPages)
        {
            //Show the back page of all previous papers
            for (int i = 0; i <= previousPaper; i++)
            {
                BookUtility.ShowPage(papers[i].Back);
                papers[i].Back.transform.SetParent(BookPanel.transform);
                papers[i].Back.transform.SetSiblingIndex(i);
                BookUtility.CopyTransform(LeftPageTransform.transform, papers[i].Back.transform);
            }

            //Show the front page of all next papers
            for (int i = papers.Length - 1; i >= currentPaper; i--)
            {
                BookUtility.ShowPage(papers[i].Front);
                papers[i].Front.transform.SetSiblingIndex(papers.Length - i + previousPaper);
                BookUtility.CopyTransform(RightPageTransform.transform, papers[i].Front.transform);
            }

        }
        else
        {
            //show back of previous page only
            if (previousPaper >= 0)
            {
                BookUtility.ShowPage(papers[previousPaper].Back);
                //papers[previousPaper].Back.transform.SetParent(BookPanel.transform);
                //papers[previousPaper].Back.transform.SetSiblingIndex(previousPaper);
                BookUtility.CopyTransform(LeftPageTransform.transform, papers[previousPaper].Back.transform);
            }
            //show front of current page only
            if (currentPaper <= papers.Length - 1)
            {
                BookUtility.ShowPage(papers[currentPaper].Front);
                papers[currentPaper].Front.transform.SetSiblingIndex(papers.Length - currentPaper + previousPaper);
                BookUtility.CopyTransform(RightPageTransform.transform, papers[currentPaper].Front.transform);

            }
        }
        #region Shadow Effect
        if (enableShadowEffect)
        {
            //the shadow effect enabled
            if (previousPaper >= 0)
            {
                //has at least one previous page, then left shadow should be active
                LeftPageShadow.gameObject.SetActive(true);
                LeftPageShadow.transform.SetParent(papers[previousPaper].Back.transform, true);
                LeftPageShadow.rectTransform.anchoredPosition = new Vector3();
                LeftPageShadow.rectTransform.localRotation = Quaternion.identity;
            }
            else
            {
                //if no previous pages, the leftShaow should be disabled
                LeftPageShadow.gameObject.SetActive(false);
                LeftPageShadow.transform.SetParent(BookPanel, true);
            }

            if (currentPaper < papers.Length)
            {
                //has at least one next page, the right shadow should be active
                RightPageShadow.gameObject.SetActive(true);
                RightPageShadow.transform.SetParent(papers[currentPaper].Front.transform, true);
                RightPageShadow.rectTransform.anchoredPosition = new Vector3();
                RightPageShadow.rectTransform.localRotation = Quaternion.identity;
            }
            else
            {
                //no next page, the right shadow should be diabled
                RightPageShadow.gameObject.SetActive(false);
                RightPageShadow.transform.SetParent(BookPanel, true);
            }
        }
        else
        {
            //Enable Shadow Effect is Unchecked, all shadow effects should be disabled
            LeftPageShadow.gameObject.SetActive(false);
            LeftPageShadow.transform.SetParent(BookPanel, true);

            RightPageShadow.gameObject.SetActive(false);
            RightPageShadow.transform.SetParent(BookPanel, true);
            
        }
        #endregion
    }

  
    //mouse interaction events call back
    public void OnMouseDragRightPage()
    {
        Controll._isClcik = false;
        //Debug.Log("111111111ss");
        if (interactable && !tweening)
        {
           
            Debug.Log("111111111ss");
            DragRightPageToPoint(transformPointMousePosition(Input.mousePosition));
        }

    }
    public void DragRightPageToPoint(Vector3 point,bool isClick=false,int count=1)
    {
        if (currentPaper > EndFlippingPaper) return;
        pageDragging = true;
        mode = FlipMode.RightToLeft;
        f = point;

        ClippingPlane.rectTransform.pivot = new Vector2(1, 0.35f);
        //Debug.Log("currentPaper: " + currentPaper);
        for (int i = 0; i < papers.Length; i++)
        {
            papers[i].Front.GetComponent<Image>().gameObject.SetActive(true);
            papers[i].Back.GetComponent<Image>().gameObject.SetActive(true);
        }
        currentPaper += count;
        for (int i = 1; i <count; i++) // 8 6 4  i:1 2 3
        {
            papers[currentPaper - i].Front.GetComponent<Image>().gameObject.SetActive(false);
        }
        //UpdatePages();

        Left = papers[currentPaper - count].Front.GetComponent<Image>();
        //Debug.Log("Left: " + Left.name);//滑动的那个
        BookUtility.ShowPage(Left.gameObject);
        Left.rectTransform.pivot = new Vector2(0, 0);
        Left.transform.position = RightPageTransform.transform.position;
        Left.transform.localEulerAngles = new Vector3(0, 0, 0);

        for (int i = 2; i <= count; i++) //
        {
            papers[currentPaper - i].Back.GetComponent<Image>().gameObject.SetActive(false);
            //Debug.Log("papers[currentPaper - i].Back: " + papers[currentPaper - i].Back.name);
        }
        Right = papers[currentPaper - 1].Back.GetComponent<Image>();
        //Debug.Log("Right: " + Right.name);
        BookUtility.ShowPage(Right.gameObject);
        Right.transform.position = RightPageTransform.transform.position;
        Right.transform.localEulerAngles = new Vector3(0, 0, 0);
        
        if (enableShadowEffect) Shadow.gameObject.SetActive(true);
        ClippingPlane.gameObject.SetActive(true);
        Controll._delay = true;//翻页角好像翻了两遍,效果不大
        //UpdateBookRTLToPoint(f);
        //Debug.Log("678 678 678");
    }
    public void OnMouseDragLeftPage()
    {
        Controll._isClcik = false;
        if (interactable && !tweening)
        {
            DragLeftPageToPoint(transformPointMousePosition(Input.mousePosition));

        }

    }
    public void DragLeftPageToPoint(Vector3 point,bool isClick = false, int count = 1)
    {
        if (currentPaper <= StartFlippingPaper) return;
        pageDragging = true;
        mode = FlipMode.LeftToRight;
        f = point;
        if (isClick)
        {
            currentPaper -= count;
           // UpdatePages();
        }

        for (int i = 0; i < papers.Length; i++)
        {
            papers[i].Front.GetComponent<Image>().gameObject.SetActive(true);
            papers[i].Back.GetComponent<Image>().gameObject.SetActive(true);
        }
        ClippingPlane.rectTransform.pivot = new Vector2(0, 0.35f);

        if (isClick )
        {
            Debug.Log("currentPaper+ count: "+ (currentPaper + count));
            for (int i = currentPaper; i < currentPaper + count-1; i++)
            {
                papers[i].Back.GetComponent<Image>().gameObject.SetActive(false);
            }
            Right = papers[currentPaper+count-1].Back.GetComponent<Image>();
        }
        else
        {
            Right = papers[currentPaper-1].Back.GetComponent<Image>();
        }
        Debug.Log("Right name: " + papers[currentPaper - 1].Back.name);
        BookUtility.ShowPage(Right.gameObject);
        Right.transform.position = LeftPageTransform.transform.position;
        Right.transform.localEulerAngles = new Vector3(0, 0, 0);
        Right.transform.SetAsFirstSibling();

        if (isClick)
        {            
            Left = papers[currentPaper].Front.GetComponent<Image>();            
        }
        else
        {
            Left = papers[currentPaper-1].Front.GetComponent<Image>();
        }
        //Debug.Log("Left name: " + papers[currentPaper - 1].Front.name);
        BookUtility.ShowPage(Left.gameObject);
        Left.gameObject.SetActive(true);
        Left.rectTransform.pivot = new Vector2(1, 0);
        Left.transform.position = LeftPageTransform.transform.position;
        Left.transform.localEulerAngles = new Vector3(0, 0, 0);


        if (enableShadowEffect) ShadowLTR.gameObject.SetActive(true);
        ClippingPlane.gameObject.SetActive(true);
        Controll._delay = true;//翻页角好像翻了两遍,效果不大
        //UpdateBookLTRToPoint(f);
       
    }
    public void OnMouseRelease()
    {
        if (interactable )
            ReleasePage();
    }
    public void ReleasePage()
    {
        //Debug.Log("sssssfffff");
        if (pageDragging)
        {
            pageDragging = false;
            float distanceToLeft = Vector2.Distance(c, ebl);
            float distanceToRight = Vector2.Distance(c, ebr);
            
            if (distanceToRight < distanceToLeft && mode == FlipMode.RightToLeft)
            {          
                TweenBack();
            }                
            else if (distanceToRight > distanceToLeft && mode == FlipMode.LeftToRight)
            {                
                TweenBack();
            }
                
            else
            {
                TweenForward();
            }
               
        }
    }

    // Update is called once per frame
    void Update()
    {
        
        if (pageDragging && interactable&&!Controll._isClcik)
        {
            Debug.Log("ddddfffffgggg");
            UpdateBook();
        }
        if(Input.GetKeyDown(KeyCode.A))
        {
            currentPaper = 5;
            UpdatePages();
        }
        //Debug.Log("isFlipping: " + isFlipping);
        if (isFlipping)
        {
            //Debug.Log("Controll._delay: ");
            elapsedTime += Time.deltaTime;
            //Debug.Log("elapsedTime: " + elapsedTime);
            //Debug.Log("duration: " + duration2);
            if (elapsedTime < duration2)
            {
                //Debug.Log("flipMode22: " + flipMode);
                if (flipMode == FlipMode.RightToLeft)
                {
                    //Debug.Log("12121212");                  
                    float x = xc + (0.5f - elapsedTime / duration2) * 2 * (pageWidth);
                    float y = (-pageHeight / (pageWidth * pageWidth)) * (x - xc) * (x - xc);
                    ControledBook.UpdateBookRTLToPoint(new Vector3(x, y, 0));
                }
                else
                {
                    //Debug.Log("34343434343");
                    float x = xc - (0.5f - elapsedTime / duration2) * 2 * (pageWidth);
                    float y = (-pageHeight / (pageWidth * pageWidth)) * (x - xc) * (x - xc);
                    ControledBook.UpdateBookLTRToPoint(new Vector3(x, y, 0));
                }

            }
            else
            {
                ControledBook.Flip();
               
                //Debug.Log("ControledBook.Flip");
                isFlipping = false;
                //this.enabled = false;
                Controll._delay = false;
                if (finish != null)
                    finish();
            }
        }
    }
    public void UpdateBook()
    {
        Debug.Log("567 567");
        f = Vector3.Lerp(f, transformPointMousePosition(Input.mousePosition), Time.deltaTime * 10);
        if (mode == FlipMode.RightToLeft)
            UpdateBookRTLToPoint(f);
        else
            UpdateBookLTRToPoint(f);
    }
    
    /// <summary>
    /// This function called when the page dragging point reached its distenation after releasing the mouse
    /// This function will call the OnFlip invocation list
    /// if you need to call any fnction after the page flipped just add it to the OnFlip invocation list
    /// </summary>
    public void Flip()
    {
        pageDragging = false;
        //Debug.Log("Flip Flip Flip");
        if (mode == FlipMode.LeftToRight)
        {
            if (Controll._isClcik)
            {
                currentPaper -= 0;
            }
            else
            {
                currentPaper -= 1;
            }
        }
            
            
        //Debug.Log("Flip: "+currentPaper);
        Left.transform.SetParent(BookPanel.transform, true);
        Left.rectTransform.pivot = new Vector2(0, 0);
        Right.transform.SetParent(BookPanel.transform, true);
        UpdatePages();
        Shadow.gameObject.SetActive(false);
        ShadowLTR.gameObject.SetActive(false);
        ClippingPlane.gameObject.SetActive(false);
        if (OnFlip != null)
            OnFlip.Invoke();
        Controll.currentPage = currentPaper;

    }

    public void TweenForward()
    {
        if (mode == FlipMode.RightToLeft)
        {
            tweening = true;
            Tween.ValueTo(gameObject, f, ebl * 0.98f, 0.3f, TweenUpdate, ()=> {
                Flip();
                //Debug.Log("ddddaaaa");
                tweening = false;
            });
        }
        else
        {
            tweening = true;
            Tween.ValueTo(gameObject, f, ebr * 0.98f, 0.3f, TweenUpdate, () => {
                Flip();
                //Debug.Log("ddddeeeee");
                tweening = false;
            });
        }
    }
    void TweenUpdate(Vector3 follow)
    {
        if (mode == FlipMode.RightToLeft)
            UpdateBookRTLToPoint(follow);
        else
            UpdateBookLTRToPoint(follow);
    }

    public void TweenBack()
    {
        if (mode == FlipMode.RightToLeft)
        {
            tweening = true;
            Tween.ValueTo(gameObject, f, ebr * 0.98f, 0.3f, TweenUpdate, () =>
            {
                currentPaper -= 1;
                Right.transform.SetParent(BookPanel.transform);
                Left.transform.SetParent(BookPanel.transform);
                //pageDragging = false;
                tweening = false;
                Shadow.gameObject.SetActive(false);
                ShadowLTR.gameObject.SetActive(false);
                UpdatePages();
            });
        }
        else
        {
            tweening = true;
            Tween.ValueTo(gameObject, f, ebl * 0.98f, 0.3f, TweenUpdate, () =>
            {
                Left.transform.SetParent(BookPanel.transform);
                Right.transform.SetParent(BookPanel.transform);
                //pageDragging = false;
                tweening = false;
                Shadow.gameObject.SetActive(false);
                ShadowLTR.gameObject.SetActive(false);
                UpdatePages();
            });
        }
    }

    #region Page Curl Internal Calculations
    //for more info about this part please check this link : http://rbarraza.com/html5-canvas-pageflip/

    float radius1, radius2;
    //Spine Bottom
    Vector3 sb;
    //Spine Top
    Vector3 st;
    //corner of the page
    Vector3 c;
    //Edge Bottom Right
    Vector3 ebr;
    //Edge Bottom Left
    Vector3 ebl;
    //follow point 
    Vector3 f;

    /// <summary>
    /// 计算卷曲临界点
    /// </summary>
    private void CalcCurlCriticalPoints()
    {
        sb = new Vector3(0, -BookPanel.rect.height / 2);
        ebr = new Vector3(BookPanel.rect.width / 2, -BookPanel.rect.height / 2);
        ebl = new Vector3(-BookPanel.rect.width / 2, -BookPanel.rect.height / 2);
        st = new Vector3(0, BookPanel.rect.height / 2);
        radius1 = Vector2.Distance(sb, ebr);
        //Debug.Log("radius1: " + radius1);
        float pageWidth = BookPanel.rect.width / 2.0f;
        float pageHeight = BookPanel.rect.height;
        radius2 = Mathf.Sqrt(pageWidth * pageWidth + pageHeight * pageHeight);
    }
    public void UpdateBookRTLToPoint(Vector3 followLocation)//followLocation 鼠标点的坐标
    {
        mode = FlipMode.RightToLeft;
        f = followLocation;
        if (enableShadowEffect)
        {
            Shadow.transform.SetParent(ClippingPlane.transform, true);
            Shadow.transform.localPosition = new Vector3(0, 0, 0);
            Shadow.transform.localEulerAngles = new Vector3(0, 0, 0);

            ShadowLTR.transform.SetParent(Left.transform);
            ShadowLTR.rectTransform.anchoredPosition = new Vector3();
            ShadowLTR.transform.localEulerAngles = Vector3.zero;
            ShadowLTR.gameObject.SetActive(true);
        }
        Right.transform.SetParent(ClippingPlane.transform, true);

        Left.transform.SetParent(BookPanel.transform, true);
        //Debug.Log("followLocation: " + followLocation);
        c = Calc_C_Position(followLocation);
        Vector3 t1;
        float T0_T1_Angle = Calc_T0_T1_Angle(c, ebr, out t1);
        if (T0_T1_Angle >= -90) T0_T1_Angle -= 180;

        ClippingPlane.rectTransform.pivot = new Vector2(1, 0.35f);
        ClippingPlane.transform.localEulerAngles = new Vector3(0, 0, T0_T1_Angle + 90);
        ClippingPlane.transform.position = BookPanel.TransformPoint(t1);


        RightPageShadow.transform.localEulerAngles = new Vector3(0, 0, T0_T1_Angle + 90);
        RightPageShadow.transform.position = BookPanel.TransformPoint(t1);

        //page position and angle
        Right.transform.position = BookPanel.TransformPoint(c);
        float C_T1_dy = t1.y - c.y;
        float C_T1_dx = t1.x - c.x;
        float C_T1_Angle = Mathf.Atan2(C_T1_dy, C_T1_dx) * Mathf.Rad2Deg;
        Right.transform.localEulerAngles = new Vector3(0, 0, C_T1_Angle - (T0_T1_Angle + 90));

        Left.transform.SetParent(ClippingPlane.transform, true);
        Left.transform.SetAsFirstSibling();

        Shadow.rectTransform.SetParent(Right.rectTransform, true);
        Controll._delay = true;
        Debug.Log("121 121 121");
    }
    public void UpdateBookLTRToPoint(Vector3 followLocation)
    {
        mode = FlipMode.LeftToRight;
        f = followLocation;
        if (enableShadowEffect)
        {
            ShadowLTR.transform.SetParent(ClippingPlane.transform, true);
            ShadowLTR.transform.localPosition = new Vector3(0, 0, 0);
            ShadowLTR.transform.localEulerAngles = new Vector3(0, 0, 0);

            Shadow.transform.SetParent(Right.transform);
            Shadow.rectTransform.anchoredPosition = new Vector3(0, 0, 0);
            Shadow.transform.localEulerAngles = Vector3.zero;
            Shadow.gameObject.SetActive(true);
        }
        Left.transform.SetParent(ClippingPlane.transform, true);
        Right.transform.SetParent(BookPanel.transform, true);

        c = Calc_C_Position(followLocation);
        Vector3 t1;
        float T0_T1_Angle = Calc_T0_T1_Angle(c, ebl, out t1);
        if (T0_T1_Angle < 0) T0_T1_Angle += 180;

        ClippingPlane.transform.localEulerAngles = new Vector3(0, 0, T0_T1_Angle - 90);
        ClippingPlane.transform.position = BookPanel.TransformPoint(t1);

        LeftPageShadow.transform.localEulerAngles = new Vector3(0, 0, T0_T1_Angle - 90);
        LeftPageShadow.transform.position = BookPanel.TransformPoint(t1);

        //page position and angle
        Left.transform.position = BookPanel.TransformPoint(c);
        float C_T1_dy = t1.y - c.y;
        float C_T1_dx = t1.x - c.x;
        float C_T1_Angle = Mathf.Atan2(C_T1_dy, C_T1_dx) * Mathf.Rad2Deg;
        Left.transform.localEulerAngles = new Vector3(0, 0, C_T1_Angle - 180 - (T0_T1_Angle - 90));

        Right.transform.SetParent(ClippingPlane.transform, true);
        Right.transform.SetAsFirstSibling();
        //Debug.Log("Right333333: " + Right.name);
        ShadowLTR.rectTransform.SetParent(Left.rectTransform, true);
        Controll._delay = true;
        Debug.Log("345 345 345");
    }
    private float Calc_T0_T1_Angle(Vector3 c, Vector3 bookCorner, out Vector3 t1)
    {
        Vector3 t0 = (c + bookCorner) / 2;
        float T0_CORNER_dy = bookCorner.y - t0.y;
        float T0_CORNER_dx = bookCorner.x - t0.x;
        float T0_CORNER_Angle = Mathf.Atan2(T0_CORNER_dy, T0_CORNER_dx);
        float T0_T1_Angle = 90 - T0_CORNER_Angle;

        float T1_X = t0.x - T0_CORNER_dy * Mathf.Tan(T0_CORNER_Angle);
        T1_X = normalizeT1X(T1_X, bookCorner, sb);
        t1 = new Vector3(T1_X, sb.y, 0);
        
        //clipping plane angle=T0_T1_Angle
        float T0_T1_dy = t1.y - t0.y;
        float T0_T1_dx = t1.x - t0.x;
        T0_T1_Angle = Mathf.Atan2(T0_T1_dy, T0_T1_dx) * Mathf.Rad2Deg;
        return T0_T1_Angle;
    }
    private float normalizeT1X(float t1, Vector3 corner, Vector3 sb)
    {
        if (t1 > sb.x && sb.x > corner.x)
            return sb.x;
        if (t1 < sb.x && sb.x < corner.x)
            return sb.x;
        return t1;
    }
    private Vector3 Calc_C_Position(Vector3 followLocation)
    {
        Vector3 c;
        f = followLocation;
        float F_SB_dy = f.y - sb.y;
        float F_SB_dx = f.x - sb.x;
        float F_SB_Angle = Mathf.Atan2(F_SB_dy, F_SB_dx);
        Vector3 r1 = new Vector3(radius1 * Mathf.Cos(F_SB_Angle), radius1 * Mathf.Sin(F_SB_Angle), 0) + sb;

        float F_SB_distance = Vector2.Distance(f, sb);
        if (F_SB_distance < radius1)
        {
            //Debug.Log("dddddd");
            c = f;
        }
            
        else
        {
            //Debug.Log("ccccccc");
            c = r1;
        }
            
        float F_ST_dy = c.y - st.y;
        float F_ST_dx = c.x - st.x;
        float F_ST_Angle = Mathf.Atan2(F_ST_dy, F_ST_dx);
        Vector3 r2 = new Vector3(radius2 * Mathf.Cos(F_ST_Angle),
           radius2 * Mathf.Sin(F_ST_Angle), 0) + st;
        float C_ST_distance = Vector2.Distance(c, st);
        if (C_ST_distance > radius2)//上半部分折
        {
            //Debug.Log("aaaaaaaaaa");
            c = r2;
        }
            
        return c;
    }
    #endregion

    #region  直接点击到某一页

    bool isPageFlipping = false;
    public BookPro ControledBook;
    public float PageFlipTime = 1;
    bool isFlipping = false;
    float elapsedTime = 0;
    private  float duration2;
    float xc, pageWidth, pageHeight;
    FlipMode flipMode;
    Action finish;
    public void FlipRightPage(bool isClick = false, int count = 1)
    {
        if (isPageFlipping) return;
        //if (Controll._delay) return;
        if (ControledBook.CurrentPaper >= ControledBook.papers.Length) return;
        isPageFlipping = true;
        //Controll._delay = true;
        FlipPage(ControledBook, PageFlipTime, FlipMode.RightToLeft, () => { isPageFlipping = false; }, true, count);
    }
    public void FlipLeftPage(bool isClick = false, int count = 1)
    {
        //Debug.Log("FlipLeftPage FlipLeftPage");
        if (isPageFlipping) return;
        //if (Controll._delay) return;
        if (ControledBook.CurrentPaper <= 0) return;
        isPageFlipping = true;
        FlipPage(ControledBook, PageFlipTime, FlipMode.LeftToRight, () => { isPageFlipping = false; }, true, count);
    }
    public  void FlipPage(BookPro book,float duration, FlipMode mode, Action OnComplete, bool isClick = false, int count = 1)
    {
        Debug.Log("FlipPage FlipPage");
        PageFlipper flipper = book.GetComponent<PageFlipper>();
        if (!flipper)
            flipper = book.gameObject.AddComponent<PageFlipper>();
        flipper.enabled = true;
        flipper.book = book;
        isFlipping = true;
        duration2 = duration- Time.deltaTime;
        //Debug.Log("duration: " + duration);
        finish = OnComplete;
        xc=(book.EndBottomLeft.x+book.EndBottomRight.x)/ 2;
        pageWidth = (book.EndBottomRight.x - book.EndBottomLeft.x) / 2;
        pageHeight = Mathf.Abs(book.EndBottomRight.y);
        flipMode = mode;
        //Debug.Log("flipMode: " + flipMode);
        //Debug.Log("mode: " + mode);
        elapsedTime = 0;
        float x;
        if (mode == FlipMode.RightToLeft)
        {
            //Debug.Log("1212121212121");
            x =xc + (pageWidth * 0.99f);
            float y = (pageHeight / (pageWidth * pageWidth)) * (x - xc) * (x - xc);
            book.DragRightPageToPoint(new Vector3(x, y, 0),true,count );
        }
        else
        {
            //Debug.Log("2323232323232");
            x = xc - (pageWidth * 0.99f);
            float y = (pageHeight / (pageWidth *pageWidth)) * (x - xc) * (x - xc);
            book.DragLeftPageToPoint(new Vector3(x, y, 0),true, count);
        }
    }
    // Update is called once per frame

    #endregion 

}
[Serializable]
public class Paper
{
    public GameObject Front;
    public GameObject Back;
}


public static class BookUtility
{
    /// <summary>
    /// Call this function to Show a Hidden Page
    /// </summary>
    /// <param name="page">the page to be shown</param>
    public static void ShowPage(GameObject page)
    {
        CanvasGroup cgf = page.GetComponent<CanvasGroup>();
        cgf.alpha = 1;
        cgf.blocksRaycasts = true;
    }

    /// <summary>
    /// Call this function to hide any page
    /// </summary>
    /// <param name="page">the page to be hidden</param>
    public static void HidePage(GameObject page)
    {
        CanvasGroup cgf = page.GetComponent<CanvasGroup>();
        cgf.alpha = 0;
        cgf.blocksRaycasts = false;
        page.transform.SetAsFirstSibling();
    }

    public static void CopyTransform(Transform from, Transform to)
    {
        to.position = from.position;
        to.rotation = from.rotation;
        to.localScale = from.localScale;

    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Controll : MonoBehaviour
{

    public static int currentPage;
    //public AutoFlip _autoFlip;
    public BookPro bookPro;
    public static bool _isClcik;
    public static bool _delay;
    // Start is called before the first frame update
    void Start()
    {
        
    }

    private bool isClick;
    private int _index;
    public void OnClickNameButton(int index)
    {
        isClick = true;
        _index = index;
        isDelay = true;
        _isClcik = true;
        //Debug.Log("currentPage: " + currentPage);
        if (_index < currentPage)
        {
            Debug.Log("ssssdddd");
            bookPro.FlipLeftPage(true, currentPage - _index);
          
        }
        if (_index > currentPage)
        {
            
            bookPro.FlipRightPage(true, _index- currentPage);
            
        }
        //for (int i = 0; i < mediaPlayers.Length; i++)
        //{
        //    //mediaPlayers[i].Pause();
        //    mediaPlayers[i].Rewind(true);
        //}
    }

    private float count;
    private bool isDelay;
    // Update is called once per frame
    void Update()
    {
        //bookPro.enabled = true;
        //if (isClick)
        //{
        //    if (_index != currentPage)
        //    {
        //        if (isDelay)
        //        {
        //            if (_index < currentPage)
        //            {
        //                _autoFlip.FlipLeftPage();
        //            }
        //            if (_index > currentPage)
        //            {
        //                _autoFlip.FlipRightPage();
        //            }
        //            isDelay = false;
        //        }
        //        if (count < 0.1f)
        //        {
        //            count += Time.deltaTime;
        //        }
        //        else
        //        {
        //            count = 0;
        //            isDelay = true;
        //        }
        //        //for (int i = 0; i < mediaPlayers.Length; i++)
        //        //{
        //        //    mediaPlayers[i].Rewind(true);
        //        //}
        //    }
        //    else
        //    {
        //        isClick = false;
        //    }

        //}
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

rain_love_snow

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值