标签:
需要在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 }
以上便是关于该插件的小小理解,希望对大家有所帮助。
标签:
原文地址:http://www.cnblogs.com/Dee2015/p/4437138.html