unity商店demo学习:跑酷游戏

本文素材和代码全部来自unity asset store里面的3D Infinite Runner Toolkit项目


步骤

场景一:TitleScene

原文链接:http://blog.csdn.net/u012234115/article/details/46119683
1 搭建开始界面场景
unity商店demo学习:跑酷游戏_第1张图片
这个场景是开启游戏的第一个界面,用于选择切换到正式游戏场景或者商店。
只需要拖入主场景模型和一个角色模型即可,并添加UI资源。

2 添加角色动画逻辑和场景切换逻辑脚本
将要切换的脚本设置为一个变量名,然后切换场景的脚本就可以在不同button间复用
[csharp]  view plain  copy
 print ?
  1. "white-space:pre">    void OnMouseUpAsButton(){  
  2.         this.guiTexture.texture = normal;  
  3.         Application.LoadLevel (levelName);  
  4.     }  

场景二:Shop

1 搭建商店界面场景
unity商店demo学习:跑酷游戏_第2张图片
商店场景用于角色选择和购买,当然还可以扩展其他功能,比如购买道具什么的。
也是导入相关模型就行了,添加UI资源。

2 界面交互基本逻辑脚本
触摸(光标滑动)
[csharp]  view plain  copy
 print ?
  1. "white-space:pre">    IEnumerator SelectDirection(){  
  2.         bool input = false;  
  3.         while (input == false) {  
  4.             if((Input.mousePosition.x - getMousePos.x) < -40){  
  5.                 indexSelect++;  
  6.                 if(indexSelect >= players.Length-1){  
  7.                     indexSelect = players.Length-1;  
  8.                 }  
  9.                 input = true;  
  10.             }  
  11.   
  12.             if((Input.mousePosition.x - getMousePos.x) > 40){  
  13.                 indexSelect--;  
  14.                 if(indexSelect <= 0){  
  15.                     indexSelect = 0;  
  16.                 }  
  17.                 input = true;  
  18.             }  
  19.   
  20.             if(Input.GetMouseButtonUp(0)){  
  21.                 input = true;  
  22.             }  
  23.             yield return 0;  
  24.         }  
角色移位
[csharp]  view plain  copy
 print ?
  1. "white-space:pre">    IEnumerator MoveToPoint(){  
  2.         while (Vector3.Distance(transform.position, point[indexSelect]) > 0.01f) {  
  3.             transform.position = Vector3.Lerp(transform.position, point[indexSelect], 10 * Time.deltaTime);  
  4.             yield return 0;  
  5.         }  
  6.   
  7.         transform.position = point [indexSelect];  
  8.   
  9.         StartCoroutine (WaitInput ());  
  10.     }  

场景三:PlayGame

1 搭建游戏初始场景
unity商店demo学习:跑酷游戏_第3张图片
载入街道等初始模型到场景,调整漫反射光

2 添加游戏角色
unity商店demo学习:跑酷游戏_第4张图片

给角色添加刚体、碰撞体、控制脚本和动画控制器,然后存为预设体。
角色控制有跳、滑,左移右移还有二段跳,分别重写了键盘控制和触摸控制的接口。
[csharp]  view plain  copy
 print ?
  1. "white-space:pre">    IEnumerator MoveBack(){  
  2.         float z = transform.position.z-0.5f;  
  3.         bool complete = false;  
  4.         while(complete == false){  
  5.             transform.position = Vector3.Lerp(transform.position, new Vector3(transform.position.x,transform.position.y,z),2*Time.deltaTime);  
  6.             if((transform.position.z - z) < 0.05f){  
  7.                 complete = true;  
  8.             }  
  9.             yield return 0;  
  10.         }  
  11.           
  12.         yield return 0;  
  13.     }  
  14.       
  15.     private void MoveForward(){  
  16.         speedMove = GameAttribute.gameAttribute.speed;  
  17.           
  18.         if(characterController.isGrounded){  
  19.             moveDir = Vector3.zero;  
  20.             if(directInput == DirectionInput.Up){  
  21.                 Jump();  
  22.                 if(isDoubleJump){  
  23.                     jumpSecond = true;    
  24.                 }  
  25.             }  
  26.         }else{  
  27.             if(directInput == DirectionInput.Down){  
  28.                 QuickGround();  
  29.             }  
  30.             if(directInput == DirectionInput.Up){  
  31.                 if(jumpSecond){  
  32.                     JumpSeccond();  
  33.                     jumpSecond = false;  
  34.                 }  
  35.             }  
  36.               
  37.             if(animationManager.animationState != animationManager.Jump  
  38.                 && animationManager.animationState != animationManager.JumpSecond  
  39.                 && animationManager.animationState != animationManager.Roll){  
  40.                 animationManager.animationState = animationManager.JumpLoop;  
  41.             }  
  42.         }  
  43.         moveDir.z = 0;  
  44.         moveDir += this.transform.TransformDirection(Vector3.forward*speedMove);  
  45.         moveDir.y -= gravity * Time.deltaTime;  
  46.   
  47.         CheckSideCollision ();  
  48.         characterController.Move((moveDir+direction)*Time.deltaTime);  
  49.     }  
与障碍物碰撞逻辑。
[csharp]  view plain  copy
 print ?
  1. "white-space:pre">    private void CheckSideCollision(){  
  2.             if (positionStand == Position.Right) {  
  3.                 if((int)characterController.collisionFlags == 5 || characterController.collisionFlags == CollisionFlags.Sides){  
  4.                     if(transform.position.x < 1.75f && checkSideCollision == false){  
  5.                         Debug.Log("Hit");  
  6.                         CameraFollow.instace.ActiveShake();  
  7.                         positionStand = Position.Middle;  
  8.                         checkSideCollision = true;  
  9.                     }  
  10.                 }  
  11.             }  
  12.   
  13.             if (positionStand == Position.Left) {  
  14.                 if((int)characterController.collisionFlags == 5 || characterController.collisionFlags == CollisionFlags.Sides){  
  15.                     if(transform.position.x > -1.75f && checkSideCollision == false){  
  16.                         Debug.Log("Hit");  
  17.                         CameraFollow.instace.ActiveShake();  
  18.                         positionStand = Position.Middle;  
  19.                         checkSideCollision = true;  
  20.                     }  
  21.                 }  
  22.             }  
  23.   
  24.             if(positionStand == Position.Middle){  
  25.                 if((int)characterController.collisionFlags == 5 || characterController.collisionFlags == CollisionFlags.Sides){  
  26.                     if(transform.position.x < -0.05f && checkSideCollision == false){  
  27.                         Debug.Log("Hit");  
  28.                         CameraFollow.instace.ActiveShake();  
  29.                         positionStand = Position.Left;  
  30.                           
  31.                         checkSideCollision = true;  
  32.                     }else if(transform.position.x > 0.05f && checkSideCollision == false){  
  33.                         Debug.Log("Hit");  
  34.                         CameraFollow.instace.ActiveShake();  
  35.                         positionStand = Position.Right;  
  36.                         checkSideCollision = true;  
  37.                     }  
  38.                 }  
  39.             }  
  40.   
  41.         if (checkSideCollision == true) {  
  42.             countDeleyInput += Time.deltaTime;  
  43.             if(countDeleyInput >= 1f){  
  44.                 checkSideCollision = false;  
  45.                 countDeleyInput = 0;  
  46.             }  
  47.         }  
  48.     }  
金币拾取
[csharp]  view plain  copy
 print ?
  1. "white-space:pre">    public void Magnet(float time){  
  2.         StopCoroutine("CancleMagnet");  
  3.         magnet.SetActive(true);  
  4.         timeMagnet = time;  
  5.         StartCoroutine(CancleMagnet());  
  6.     }  

3 创建游戏控制器
添加空物体到场景,挂载脚本,异步加载场景、开始游戏、动态创建游戏物体,得分更新以及重置。
[csharp]  view plain  copy
 print ?
  1. "white-space:pre">    //Loading method  
  2.     IEnumerator WaitLoading(){  
  3.         while(patSysm.loadingComplete == false){  
  4.             yield return 0;   
  5.         }  
  6.         StartCoroutine(InitPlayer());  
  7.     }  
  8.       
  9.     //Spawn player method  
  10.     IEnumerator InitPlayer(){  
  11.         GameObject go = (GameObject)Instantiate(playerPref[selectPlayer], posStart, Quaternion.identity);  
  12.         cameraFol.target = go.transform;  
  13.         yield return 0;  
  14.         StartCoroutine(UpdatePerDistance());  
  15.     }  
  16.       
  17.     //update distance score  
  18.     IEnumerator UpdatePerDistance(){  
  19.         while(true){  
  20.             if(PatternSystem.instance.loadingComplete){  
  21.                 if(GameAttribute.gameAttribute.pause == false  
  22.                     && GameAttribute.gameAttribute.isPlaying == true  
  23.                     && GameAttribute.gameAttribute.life > 0){  
  24.                     if(Controller.instace.transform.position.z > 0){  
  25.                         GameAttribute.gameAttribute.distance += GameAttribute.gameAttribute.speed * Time.deltaTime;  
  26.                         distanceCheck += GameAttribute.gameAttribute.speed * Time.deltaTime;  
  27.                         if(distanceCheck >= speedAddEveryDistance){  
  28.                             GameAttribute.gameAttribute.speed += speedAdd;  
  29.                             if(GameAttribute.gameAttribute.speed >= speedMax){  
  30.                                 GameAttribute.gameAttribute.speed = speedMax;     
  31.                             }  
  32.                             countAddSpeed++;  
  33.                             distanceCheck = 0;  
  34.                         }  
  35.                     }  
  36.                 }  
  37.             }  
  38.             yield return 0;  
  39.         }  
  40.     }  
  41.       
  42.     //reset game  
  43.     public IEnumerator ResetGame(){  
  44.         GameAttribute.gameAttribute.isPlaying = false;  
  45.         GUIManager.instance.showSumGUI = true;  
  46.         int oldCoind = GameData.LoadCoin ();  
  47.         GameData.SaveCoin((int)GameAttribute.gameAttribute.coin+oldCoind);  
  48.         distanceCheck = 0;  
  49.         countAddSpeed = 0;  
  50.         yield return 0;   
  51.     }  

4 设置摄像机跟随
主摄像机挂载脚本,主要有跟随、重置和晃动逻辑
[csharp]  view plain  copy
 print ?
  1. "white-space:pre">    void LateUpdate(){  
  2.         if(target != null){  
  3.             if(target.position.z >= 0){  
  4.                 if(shake == false){  
  5.                     posCamera.x = Mathf.Lerp(posCamera.x, target.position.x, 5 * Time.deltaTime);  
  6.                     posCamera.y = Mathf.Lerp(posCamera.y, target.position.y + height, 5 * Time.deltaTime);  
  7.                     posCamera.z = Mathf.Lerp(posCamera.z, target.position.z + distance, GameAttribute.gameAttribute.speed); //* Time.deltaTime);  
  8.                     transform.position = posCamera;  
  9.                     angleCam.x = angle;  
  10.                     angleCam.y = Mathf.Lerp(angleCam.y, 0, 1 * Time.deltaTime);  
  11.                     angleCam.z = transform.eulerAngles.z;  
  12.                     transform.eulerAngles = Vector3.Lerp(transform.eulerAngles, angleCam, 1 * Time.deltaTime);  
  13.                 }  
  14.             }else{  
  15.                 if(PatternSystem.instance.loadingComplete == true){  
  16.                     Vector3 dummy = Vector3.zero;  
  17.                     posCamera.x = Mathf.Lerp(posCamera.x, 0, 5 * Time.deltaTime);  
  18.                     posCamera.y = Mathf.Lerp(posCamera.y, dummy.y + height, 5 * Time.deltaTime);  
  19.                     posCamera.z = dummy.z + distance;  
  20.                     transform.position = posCamera;  
  21.                     angleCam.x = angle;  
  22.                     angleCam.y = transform.eulerAngles.y;  
  23.                     angleCam.z = transform.eulerAngles.z;  
  24.                     transform.eulerAngles = angleCam;  
  25.                 }  
  26.             }  
  27.         }  
  28.     }  
  29.       
  30.       
  31.     //Reset camera when charater die  
  32.     public void Reset(){  
  33.         shake = false;  
  34.         Vector3 dummy = Vector3.zero;  
  35.         posCamera.x = 0;  
  36.         posCamera.y = dummy.y + height;  
  37.         posCamera.z = dummy.z + distance;  
  38.         transform.position = posCamera;  
  39.         angleCam.x = angle;  
  40.         angleCam.y = transform.eulerAngles.y;  
  41.         angleCam.z = transform.eulerAngles.z;  
  42.         transform.eulerAngles = angleCam;  
  43.     }  
  44.       
  45.     //Shake camera  
  46.     public void ActiveShake(){  
  47.         shake = true;  
  48.         StartCoroutine(ShakeCamera());    
  49.     }  

5 调整场景物体的尺寸
可以用标准立方体作为标尺来衡量场景物体的长宽高,使得游戏角色和场景物体比例得当。

6 添加游戏物体实例管理系统
创建空物体,挂载脚本,用于动态管理场景物体的更新(比如街道的无限延长,障碍物的随机产生等等)

[csharp]  view plain  copy
 print ?
  1. "white-space:pre">    IEnumerator AddBuilding(){  
  2.         QueueFloor qFloor = queneFloor[0];  
  3.         queneFloor.RemoveRange(0,1);  
  4.         int i = 0;  
  5.         randomPattern = Random.Range(0, patternBuilding.Count);  
  6.         randomItem = Random.Range(0, patternItem.Count);  
  7.         while(i < building_Script.Count){  
  8.             int j = 0;  
  9.             while(j < patternBuilding[randomPattern].stateBuilding_Left.Length){  
  10.                 CheckAddBuilding_Left(i,j,qFloor);  
  11.                 j++;  
  12.             }  
  13.             j = 0;  
  14.             while(j < patternBuilding[randomPattern].stateBuilding_Right.Length){  
  15.                 CheckAddBuilding_Right(i,j,qFloor);  
  16.                 j++;  
  17.             }  
  18.             i++;      
  19.         }  
  20.         yield return 0;  
  21.         i = 0;  
  22.         CheckTypeItemFormAdd(qFloor, i);  
  23.         yield return 0;  
  24.         qFloor.floorObj.transform.position = posFloorLast;  
  25.         posFloorLast.z += nextPosFloor;  
  26.         queneFloor.Add(qFloor);  
  27.         StartCoroutine(WaitCheckFloor());  
  28.         yield return 0;  
  29.     }  

[csharp]  view plain  copy
 print ?
  1. "white-space:pre">    void AddItemWihtType_SubRight(QueueFloor floor, int slotIndex,int type){  
  2.         if(patternItem[randomItem].itemType_SubRight[slotIndex].x == type){  
  3.             int j = 0;  
  4.             while(j < amount_Item_Pattern_SubRight[type-1]){  
  5.                 if(j < item_Type_Script[type-1].itemList.Count){  
  6.                     if(item_Type_Script[type-1].itemList[j].itemActive == false  
  7.                        && floor.floorItemSlotClass.floor_Slot_SubRight[slotIndex] == false){  
  8.                         SetPosItem_SubRight_For_Type(slotIndex,type-1,j,floor, patternItem[randomItem].itemType_SubRight[slotIndex].y);  
  9.                         j = 0;  
  10.                     }  
  11.                 }  
  12.                 j++;  
  13.             }  
  14.         }     
  15.     }  

7 设置障碍物摆放
这里用到unity一个非常棒的工具,可以用图形化的手段对内部数据结构进行配置,实现所见即所得
unity商店demo学习:跑酷游戏_第5张图片
如图,可以手动配置街道物体,接到障碍物,很好的关卡设置编辑器。

编译

将项目编译为可执行文件,需要在build设置里面添加所有scene,注意顺序。
unity商店demo学习:跑酷游戏_第6张图片

游戏效果

开始界面
unity商店demo学习:跑酷游戏_第7张图片

商店
unity商店demo学习:跑酷游戏_第8张图片

游戏中
unity商店demo学习:跑酷游戏_第9张图片

你可能感兴趣的:(unity商店demo学习:跑酷游戏)