unity商店demo学习:跑酷游戏
来源:互联网 发布:淘宝 二手 编辑:程序博客网 时间:2024/05/02 02:56
本文素材和代码全部来自unity asset store里面的3D Infinite Runner Toolkit项目
步骤
场景一:TitleScene
1 搭建开始界面场景
这个场景是开启游戏的第一个界面,用于选择切换到正式游戏场景或者商店。
只需要拖入主场景模型和一个角色模型即可,并添加UI资源。
2 添加角色动画逻辑和场景切换逻辑脚本
将要切换的脚本设置为一个变量名,然后切换场景的脚本就可以在不同button间复用
<span style="white-space:pre"></span>void OnMouseUpAsButton(){this.guiTexture.texture = normal;Application.LoadLevel (levelName);}
场景二:Shop
1 搭建商店界面场景
商店场景用于角色选择和购买,当然还可以扩展其他功能,比如购买道具什么的。
也是导入相关模型就行了,添加UI资源。
2 界面交互基本逻辑脚本
触摸(光标滑动)
<span style="white-space:pre"></span>IEnumerator SelectDirection(){bool input = false;while (input == false) {if((Input.mousePosition.x - getMousePos.x) < -40){indexSelect++;if(indexSelect >= players.Length-1){indexSelect = players.Length-1;}input = true;}if((Input.mousePosition.x - getMousePos.x) > 40){indexSelect--;if(indexSelect <= 0){indexSelect = 0;}input = true;}if(Input.GetMouseButtonUp(0)){input = true;}yield return 0;}角色移位
<span style="white-space:pre"></span>IEnumerator MoveToPoint(){while (Vector3.Distance(transform.position, point[indexSelect]) > 0.01f) {transform.position = Vector3.Lerp(transform.position, point[indexSelect], 10 * Time.deltaTime);yield return 0;}transform.position = point [indexSelect];StartCoroutine (WaitInput ());}
场景三:PlayGame
1 搭建游戏初始场景载入街道等初始模型到场景,调整漫反射光
2 添加游戏角色
给角色添加刚体、碰撞体、控制脚本和动画控制器,然后存为预设体。
角色控制有跳、滑,左移右移还有二段跳,分别重写了键盘控制和触摸控制的接口。
<span style="white-space:pre"></span>IEnumerator MoveBack(){float z = transform.position.z-0.5f;bool complete = false;while(complete == false){transform.position = Vector3.Lerp(transform.position, new Vector3(transform.position.x,transform.position.y,z),2*Time.deltaTime);if((transform.position.z - z) < 0.05f){complete = true;}yield return 0;}yield return 0;}private void MoveForward(){speedMove = GameAttribute.gameAttribute.speed;if(characterController.isGrounded){moveDir = Vector3.zero;if(directInput == DirectionInput.Up){Jump();if(isDoubleJump){jumpSecond = true;}}}else{if(directInput == DirectionInput.Down){QuickGround();}if(directInput == DirectionInput.Up){if(jumpSecond){JumpSeccond();jumpSecond = false;}}if(animationManager.animationState != animationManager.Jump&& animationManager.animationState != animationManager.JumpSecond&& animationManager.animationState != animationManager.Roll){animationManager.animationState = animationManager.JumpLoop;}}moveDir.z = 0;moveDir += this.transform.TransformDirection(Vector3.forward*speedMove);moveDir.y -= gravity * Time.deltaTime;CheckSideCollision ();characterController.Move((moveDir+direction)*Time.deltaTime);}与障碍物碰撞逻辑。
<span style="white-space:pre"></span>private void CheckSideCollision(){if (positionStand == Position.Right) {if((int)characterController.collisionFlags == 5 || characterController.collisionFlags == CollisionFlags.Sides){if(transform.position.x < 1.75f && checkSideCollision == false){Debug.Log("Hit");CameraFollow.instace.ActiveShake();positionStand = Position.Middle;checkSideCollision = true;}}}if (positionStand == Position.Left) {if((int)characterController.collisionFlags == 5 || characterController.collisionFlags == CollisionFlags.Sides){if(transform.position.x > -1.75f && checkSideCollision == false){Debug.Log("Hit");CameraFollow.instace.ActiveShake();positionStand = Position.Middle;checkSideCollision = true;}}}if(positionStand == Position.Middle){if((int)characterController.collisionFlags == 5 || characterController.collisionFlags == CollisionFlags.Sides){if(transform.position.x < -0.05f && checkSideCollision == false){Debug.Log("Hit");CameraFollow.instace.ActiveShake();positionStand = Position.Left;checkSideCollision = true;}else if(transform.position.x > 0.05f && checkSideCollision == false){Debug.Log("Hit");CameraFollow.instace.ActiveShake();positionStand = Position.Right;checkSideCollision = true;}}}if (checkSideCollision == true) {countDeleyInput += Time.deltaTime;if(countDeleyInput >= 1f){checkSideCollision = false;countDeleyInput = 0;}}}金币拾取
<span style="white-space:pre"></span>public void Magnet(float time){StopCoroutine("CancleMagnet");magnet.SetActive(true);timeMagnet = time;StartCoroutine(CancleMagnet());}
添加空物体到场景,挂载脚本,异步加载场景、开始游戏、动态创建游戏物体,得分更新以及重置。
<span style="white-space:pre"></span>//Loading methodIEnumerator WaitLoading(){while(patSysm.loadingComplete == false){yield return 0;}StartCoroutine(InitPlayer());}//Spawn player methodIEnumerator InitPlayer(){GameObject go = (GameObject)Instantiate(playerPref[selectPlayer], posStart, Quaternion.identity);cameraFol.target = go.transform;yield return 0;StartCoroutine(UpdatePerDistance());}//update distance scoreIEnumerator UpdatePerDistance(){while(true){if(PatternSystem.instance.loadingComplete){if(GameAttribute.gameAttribute.pause == false&& GameAttribute.gameAttribute.isPlaying == true&& GameAttribute.gameAttribute.life > 0){if(Controller.instace.transform.position.z > 0){GameAttribute.gameAttribute.distance += GameAttribute.gameAttribute.speed * Time.deltaTime;distanceCheck += GameAttribute.gameAttribute.speed * Time.deltaTime;if(distanceCheck >= speedAddEveryDistance){GameAttribute.gameAttribute.speed += speedAdd;if(GameAttribute.gameAttribute.speed >= speedMax){GameAttribute.gameAttribute.speed = speedMax;}countAddSpeed++;distanceCheck = 0;}}}}yield return 0;}}//reset gamepublic IEnumerator ResetGame(){GameAttribute.gameAttribute.isPlaying = false;GUIManager.instance.showSumGUI = true;int oldCoind = GameData.LoadCoin ();GameData.SaveCoin((int)GameAttribute.gameAttribute.coin+oldCoind);distanceCheck = 0;countAddSpeed = 0;yield return 0;}
主摄像机挂载脚本,主要有跟随、重置和晃动逻辑
<span style="white-space:pre"></span>void LateUpdate(){if(target != null){if(target.position.z >= 0){if(shake == false){posCamera.x = Mathf.Lerp(posCamera.x, target.position.x, 5 * Time.deltaTime);posCamera.y = Mathf.Lerp(posCamera.y, target.position.y + height, 5 * Time.deltaTime);posCamera.z = Mathf.Lerp(posCamera.z, target.position.z + distance, GameAttribute.gameAttribute.speed); //* Time.deltaTime);transform.position = posCamera;angleCam.x = angle;angleCam.y = Mathf.Lerp(angleCam.y, 0, 1 * Time.deltaTime);angleCam.z = transform.eulerAngles.z;transform.eulerAngles = Vector3.Lerp(transform.eulerAngles, angleCam, 1 * Time.deltaTime);}}else{if(PatternSystem.instance.loadingComplete == true){Vector3 dummy = Vector3.zero;posCamera.x = Mathf.Lerp(posCamera.x, 0, 5 * Time.deltaTime);posCamera.y = Mathf.Lerp(posCamera.y, dummy.y + height, 5 * Time.deltaTime);posCamera.z = dummy.z + distance;transform.position = posCamera;angleCam.x = angle;angleCam.y = transform.eulerAngles.y;angleCam.z = transform.eulerAngles.z;transform.eulerAngles = angleCam;}}}}//Reset camera when charater diepublic void Reset(){shake = false;Vector3 dummy = Vector3.zero;posCamera.x = 0;posCamera.y = dummy.y + height;posCamera.z = dummy.z + distance;transform.position = posCamera;angleCam.x = angle;angleCam.y = transform.eulerAngles.y;angleCam.z = transform.eulerAngles.z;transform.eulerAngles = angleCam;}//Shake camerapublic void ActiveShake(){shake = true;StartCoroutine(ShakeCamera());}
可以用标准立方体作为标尺来衡量场景物体的长宽高,使得游戏角色和场景物体比例得当。
6 添加游戏物体实例管理系统
创建空物体,挂载脚本,用于动态管理场景物体的更新(比如街道的无限延长,障碍物的随机产生等等)
<span style="white-space:pre"></span>IEnumerator AddBuilding(){QueueFloor qFloor = queneFloor[0];queneFloor.RemoveRange(0,1);int i = 0;randomPattern = Random.Range(0, patternBuilding.Count);randomItem = Random.Range(0, patternItem.Count);while(i < building_Script.Count){int j = 0;while(j < patternBuilding[randomPattern].stateBuilding_Left.Length){CheckAddBuilding_Left(i,j,qFloor);j++;}j = 0;while(j < patternBuilding[randomPattern].stateBuilding_Right.Length){CheckAddBuilding_Right(i,j,qFloor);j++;}i++;}yield return 0;i = 0;CheckTypeItemFormAdd(qFloor, i);yield return 0;qFloor.floorObj.transform.position = posFloorLast;posFloorLast.z += nextPosFloor;queneFloor.Add(qFloor);StartCoroutine(WaitCheckFloor());yield return 0;}
<span style="white-space:pre"></span>void AddItemWihtType_SubRight(QueueFloor floor, int slotIndex,int type){if(patternItem[randomItem].itemType_SubRight[slotIndex].x == type){int j = 0;while(j < amount_Item_Pattern_SubRight[type-1]){if(j < item_Type_Script[type-1].itemList.Count){if(item_Type_Script[type-1].itemList[j].itemActive == false && floor.floorItemSlotClass.floor_Slot_SubRight[slotIndex] == false){SetPosItem_SubRight_For_Type(slotIndex,type-1,j,floor, patternItem[randomItem].itemType_SubRight[slotIndex].y);j = 0;}}j++;}}}
这里用到unity一个非常棒的工具,可以用图形化的手段对内部数据结构进行配置,实现所见即所得
如图,可以手动配置街道物体,接到障碍物,很好的关卡设置编辑器。
编译
将项目编译为可执行文件,需要在build设置里面添加所有scene,注意顺序。游戏效果
开始界面商店
游戏中
0 0
- unity商店demo学习:跑酷游戏
- unity商店demo学习:跑酷游戏
- unity商店demo学习:俯视视角RPG游戏
- unity官方demo学习之Stealth(五)游戏控制器
- unity学习demo
- Unity游戏商店购物到背包代码笔记
- Unity 3D网页游戏 Demo 展示
- 游戏开发学习笔记(九)商店系统
- [unity] unity学习——弹球游戏
- unity学习之游戏商城
- RPG游戏商店系统
- unity 跑酷游戏开发笔记
- UNITY 跑酷学习
- unity官方demo学习:Roll-a-Ball
- unity官方demo学习:Survival Shooter
- Unity app 如何打开商店
- 抓取苹果商店游戏子类
- UNITY 跑酷学习2
- 再回首,数据结构——线性表、链表上的常见算法
- Java实现Excel导入数据库,数据库中的数据导入到Excel
- 页面布局--变化型
- Visio中UML类图符号说明及使用简介
- springMVC框架结构
- unity商店demo学习:跑酷游戏
- ImportError: No module named pysqlite2
- easyui tree 实现类似ztree的数据格式
- OC反射机制
- Spring2.5学习1.1_bean配置及其Spring容器的实例化
- IBM UrbanCode Deploy的可伸缩部署
- 绿色软件有什么特征?
- 数据库事务中获取自增ID
- (编程训练)再回首,数据结构——顺序表上的编程训练