需要在Unity实现达到仿真的翻书效果,我们一般可以借助megaFierstext插件来完成。
下载地址:http://pan.baidu.com/s/1kTorsm7
导入Unity后,打开默认scene,在MainCamera上可以看到FilpOver脚本。
这便是控制具体翻页的脚本。
代码结构分析(伪代码)如下:
在Awake()与Start()函数中:
初始化整本书:
根据Texture中贴图数量计算出书的页数创建每一页
为每一页增加三个API脚本
初始化一些控制变量
1 private float betweenHitPointX; //用于记录鼠标当前位置 2 private float nextHitPointX; //与上一个鼠标位置进行比较 3 4 private int pageNumber; //书的总页数 5 private int newPageNumber=0; //当前操作的页 6 7 public GameObject pageMasterplate; //单页模版 8 public Transform bookPosition; //生成书籍的位置 9 private GameObject[] bookPage; //每页对应的数组 10 private Object[] texAll; //用于存储所有页贴图的数组 11 private MeshRenderer meshRendererScript; //用于获取当前页MegaPageFlip脚本 12 //--------------添加每一页所需要的脚本--------------------- 13 private MegaModifyObject megaModifyObjectScript; 14 private MegaPageFlip megaPageFlipScript; 15 private MegaMeshPage MegaMeshPageScript; 16 17 private Material[] materials; //用于加载的页面的材质球 18 private Material[] material; //用来存放每张纸业的正反面 19 private float Downtime=0f; //用于存储时间变量 20 private float startTurn; 21 private bool pagefan=false; //用于标示是否翻到下一页 22 private bool pagezheng=false; //用于标示是否翻到上一页
在Update()函数中——
开启翻页状态(鼠标左键点击页面时):
获取当前活动页面脚本
将当前页的高度上移
记录当前的初始页面角度
进入翻页状态(给控制变量赋值)
1 if(Input.GetMouseButtonDown(0)&&!pagefan&&!pagezheng){ 2 Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); 3 RaycastHit hit; 4 if (Physics.Raycast(ray, out hit, 100)){ 5 if(hit.transform!=null) 6 { 7 if(hit.transform.name=="right"&&newPageNumber<pageNumber)//点击右边并且当前页小于总页数 8 { 9 megaPageFlipScript=bookPage[newPageNumber].GetComponent<MegaPageFlip>();//获取当前页脚本 10 MegaMeshPageScript=bookPage[newPageNumber].GetComponent<MegaMeshPage>(); 11 bookPage[newPageNumber].transform.localPosition=new Vector3(0,0.001f,0);//页面的位置稍微上移 12 startTurn=megaPageFlipScript.turn;//记录初始角度 13 } 14 if(hit.transform.name=="left"&&newPageNumber>0)//点击左边边并且当前页大于0 15 { 16 megaPageFlipScript=bookPage[newPageNumber-1].GetComponent<MegaPageFlip>(); 17 MegaMeshPageScript=bookPage[newPageNumber-1].GetComponent<MegaMeshPage>(); 18 bookPage[newPageNumber-1].transform.localPosition=new Vector3(0,0.001f,0); 19 startTurn=megaPageFlipScript.turn; 20 } 21 betweenHitPointX=hit.point.x; //获取中间碰撞点的X坐标 22 23 } 24 } 25 }
翻页状态(承接上一个状态,持续按下鼠标左键时):
如果鼠标左移,翻页角度减少
如果鼠标右移,翻页角度增加
1 if (Input.GetMouseButton(0)&&!pagefan&&!pagezheng&&megaPageFlipScript!=null){ 2 Ray ray1 = Camera.main.ScreenPointToRay(Input.mousePosition); 3 RaycastHit hit1; 4 if (Physics.Raycast(ray1, out hit1, 100)){ 5 if(hit1.transform!=null) 6 { 7 nextHitPointX=hit1.point.x; //获取最后的碰撞点的X坐标 8 if(nextHitPointX<betweenHitPointX){//鼠标右移 9 megaPageFlipScript.turn+=2.5f; 10 } 11 else if(nextHitPointX>betweenHitPointX){//鼠标左移 12 megaPageFlipScript.turn-=2.5f; 13 } 14 betweenHitPointX=hit1.point.x; //更新中间碰撞点的X坐标 15 } 16 } 17 }
松开手的状态(承接上一个状态,鼠标左键弹起时):
记录当前时间,用作插值处理
如果此时页面角度大于一定值,则确定页面是否成功翻页
1 if(Input.GetMouseButtonUp(0)){ 2 Downtime=Time.time;//记录时间,插值使用 3 if(megaPageFlipScript!=null){ 4 if(megaPageFlipScript.turn>40){//角度大于40,判定可以翻过去,否则翻不过去 5 pagezheng=true; 6 } 7 else{ 8 pagefan=true; 9 } 10 } 11 }
实现翻页状态(承接上一个状态,鼠标左键弹起后页面归位):
确定是翻过来了还是没有翻过来
插值得到角度改变
如果是0或100状态,说明翻页完毕
根据初始值的状态判定是否翻页完毕
1 //正向归位 2 3 if(pagefan){ 4 megaPageFlipScript.turn=Mathf.SmoothStep(megaPageFlipScript.turn, 0, Time.time-Downtime); 5 if(megaPageFlipScript.turn==0||megaPageFlipScript.turn==100)//0或100是归位状态 6 { 7 if(startTurn!=megaPageFlipScript.turn)//状态不同说明完全翻过去了 8 { 9 newPageNumber--; 10 bookPage[newPageNumber].transform.localPosition=new Vector3(0,-newPageNumber*0.001f,0);//页面下移 11 } 12 pagefan=false; 13 megaPageFlipScript=null; 14 } 15 } 16 17 //反向归位 18 if(pagezheng){ 19 megaPageFlipScript.turn=Mathf.SmoothStep(megaPageFlipScript.turn, 100, Time.time-Downtime); 20 if(megaPageFlipScript.turn==0||megaPageFlipScript.turn==100) 21 { 22 if(startTurn!=megaPageFlipScript.turn) 23 { 24 bookPage[newPageNumber].transform.localPosition=new Vector3(0,(newPageNumber-pageNumber)*0.001f,0); 25 newPageNumber++; 26 } 27 megaPageFlipScript=null; 28 pagezheng=false; 29 } 30 }
当我们熟悉代码结构后,便可以根据项目的情况进行灵活的调整翻页的效果。
下面是一个一键翻页的Demo(不需鼠标拖动):
OnGUI()中代码如下:
1 void OnGUI() 2 { 3 if(pagefan||pagezheng)//正在翻页,则操作无效 4 return; 5 if(GUI.Button(new Rect(10,10,100,20),"下一页")) 6 { 7 if(newPageNumber<pageNumber) 8 { 9 downTime=Time.time;//记录初始状态 10 megaPageFlipScript=bookPage[newPageNumber].GetComponent<MegaPageFlip>(); 11 startTurn=megaPageFlipScript.turn; 12 MegaMeshPageScript=bookPage[newPageNumber].GetComponent<MegaMeshPage>(); 13 bookPage[newPageNumber].transform.localPosition=new Vector3(0,0.001f,0); 14 pagezheng=true;//按下按钮时,将标记直接设置为true 15 } 16 } 17 if(GUI.Button(new Rect(10,30,100,20),"上一页")) 18 { 19 if(pagefan||pagezheng) 20 return; 21 if(newPageNumber>0) 22 { 23 downTime=Time.time; 24 megaPageFlipScript=bookPage[newPageNumber-1].GetComponent<MegaPageFlip>(); 25 startTurn=megaPageFlipScript.turn; 26 MegaMeshPageScript=bookPage[newPageNumber-1].GetComponent<MegaMeshPage>(); 27 bookPage[newPageNumber-1].transform.localPosition=new Vector3(0,0.001f,0); 28 pagefan=true; 29 } 30 } 31 }
在Update()里面:
isOver参数是表面是不是翻页完毕了。
1 void Update () 2 { 3 if(pagezheng&&!isOver)//正向翻页未结束 4 { 5 megaPageFlipScript.turn=Mathf.SmoothStep(megaPageFlipScript.turn,100,Time.time-downTime); 6 if(megaPageFlipScript.turn==100||megaPageFlipScript.turn==0) 7 { 8 if(startTurn!=megaPageFlipScript.turn) 9 isOver=true; 10 } 11 } 12 else if(pagefan&&!isOver)//反向翻页未结束 13 { 14 megaPageFlipScript.turn=Mathf.SmoothStep(megaPageFlipScript.turn,0,Time.time-downTime); 15 if(megaPageFlipScript.turn==100||megaPageFlipScript.turn==0) 16 { 17 if(startTurn!=megaPageFlipScript.turn) 18 isOver=true; 19 } 20 } 21 else if(pagefan&&isOver)//正相翻页结束 22 { 23 isOver=false; 24 pagefan=false; 25 newPageNumber--; 26 bookPage[newPageNumber].transform.localPosition=new Vector3(0,-newPageNumber*0.001f,0); 27 megaPageFlipScript=null; 28 } 29 else if(pagezheng&&isOver)//反向翻页结束 30 { 31 isOver=false; 32 pagezheng=false; 33 bookPage[newPageNumber].transform.localPosition=new Vector3(0,(newPageNumber-pageNumber)*0.001f,0); 34 newPageNumber++; 35 megaPageFlipScript=null; 36 } 37 }
以上便是关于该插件的小小理解,希望对大家有所帮助。
时间: 2024-11-09 04:59:35