unity3D游戏开发十二之疯狂的小球

下面我们通过一个具体的实例来了解如何使用物理引擎,该实例通过第三人称视角控制游戏中的小球对象,游戏通过是否与钻石碰撞来界定是否寻找到钻石并获得积分,获得积分满10分后,赢得游戏,当小球冲出跑道时,游戏失败,并提示是否重新开始游戏。


依次打开文件夹Assets-》object,在object文件夹下找到Runway.fbx文件,拖进场景中,如下图:


选择Runway游戏对象,修改Transform组件的Position(88,48.5,57),Rotation(270,350,0),Scale(1,1,1),然后选择Main Camera对象,修改Transform组件的Position(88,60,45),Rotation(55,0,0),Scale(1,1,1),如下图:


然后下面我们添加一个平行光源,依次打开菜单栏中的GameObject->Create Other->Directional light,修改该对象的Transform组件的Position(87,57,58),Rotation(48,-29,1),Scale(1,1,1),如下图:


然后我们添加一个球体,依次打开菜单栏GameObject->Create Other->Sphere,并命名为Ball,设置它的position(84,50,48),Rotation(0,0,0),Scale(1,1,1),然后打开菜单栏Component->Physics->Rigidbody,给Ball对象添加刚体组件,如下图:


下面给小球添加材质文件,如下图:


现在小球无法移动,所以我们得给小球绑定一个脚本,新建一个文件夹,命名为Scripts,在Scripts文件夹里新建一个C#文件,并命名为BallControl.cs,代码如下:

[csharp]  view plain copy
  1. using UnityEngine;  
  2. using System.Collections;  
  3.   
  4. public class BallControl : MonoBehaviour {  
  5.   
  6.     //小球运动的速率  
  7.     public float movementSpeed=6.0f;   
  8.     //小球的水平运动  
  9.     private Vector3 horizontalMovement;  
  10.     //小球的前后运动  
  11.     private Vector3 verticalMovement;  
  12.   
  13.   
  14.     // Use this for initialization  
  15.     void Start ()  
  16.     {  
  17.   
  18.   
  19.   
  20.   
  21.       
  22.     }  
  23.       
  24.     // Update is called once per frame  
  25.     void Update ()   
  26.     {  
  27.   
  28.         //Vector3.right x zhou  
  29.         horizontalMovement=Input.GetAxis("Horizontal")*Vector3.right*movementSpeed;  
  30.           
  31.         //z zhou  
  32.         verticalMovement=Input.GetAxis("Vertical")*Vector3.forward*movementSpeed;  
  33.           
  34.         //小球的运动  
  35.         Vector3 movement=horizontalMovement+verticalMovement;  
  36.           
  37.         //为小球施加力  
  38.         rigidbody.AddForce(movement,ForceMode.Force);  
  39.   
  40.       
  41.     }  
  42. }  
然后绑定到Ball对象上,如下图:


点击Play按钮,我们发现可以用键盘控制小球移动了,如下图:

下面我们添加钻石游戏对象,将Gem.fbx文件拖进场景中,复制10个这样的对象,然后依次命名Gem1--Gem10,依次打开菜单栏创建一个空游戏对象,命名Gems,然后把Gem1-10都拖进Gems对象中,如下图:


依次设置Gem1-Gem10对象的Transform组件属性,Gem1的Position(78,50,55),Rotation(-90,0,0),Scale(0.27,0.27,0.27),并再Mesh Collider组件下勾选Is Trigger,设置tag为Pickup,依次设置剩下的gem对象,设好后如下图:


我们修改下BallControl.cs脚本,当小球与钻石碰撞时,让钻石消失,添加代码如下:

[csharp]  view plain copy
  1. void OnTriggerEnter(Collider other)  
  2.     {  
  3.         //判断小球是否与钻石对象碰撞  
  4.         if (other.tag == "Pickup")  
  5.         {  
  6.                   
  7.             //销毁对象  
  8.             Destroy(other.gameObject);  
  9.           
  10.           
  11.           
  12.           
  13.         }  
  14.   
  15.   
  16.   
  17.   
  18.     }  

接下来,我们创建一个平面,依次打开菜单栏GameObject->Create Other->Cune,命名为GameOverTrigger,该对象用于判断小球是否与其碰撞,如果是,表示小球冲出了跑道,游戏失败,我们设置Transform组件属性,Position(90,40,55),Rotation(0,0,0),Scale(165,1,118),如下图:


勾选Box Collider下的Is Trigger复选框,并取消勾选Mesh Renderer组件,创建一个c#脚本,叫GameOverTrigger.cs,代码如下:

[csharp]  view plain copy
  1. using UnityEngine;  
  2. using System.Collections;  
  3.   
  4. public class GameOverTrigger : MonoBehaviour {  
  5.   
  6.     void OnTriggerEnter()  
  7.     {  
  8.           
  9.   
  10.         Debug.Log("over");  
  11.     }  
  12. }  

把脚本绑定到GameOverTrigger对象上,预览游戏,当小球冲出跑道后,我们打印over字样。接下来我们在新建一个脚本,叫CrayBallManager.cs,用来处理一些输赢得分之类的逻辑,代码如下:

[csharp]  view plain copy
  1. using UnityEngine;  
  2. using System.Collections;  
  3.   
  4. //枚举  
  5. public enum CrazyBallState { playing, won, lost };  
  6.   
  7. public class CrazyBallManager : MonoBehaviour  
  8. {     
  9.   
  10.     //单例  
  11.     public static CrazyBallManager CB;  
  12.   
  13.     //按钮  
  14.     public GUIStyle buttonStyle;  
  15.   
  16.     //标签  
  17.     public GUIStyle labelStyle;  
  18.   
  19.     //钻石总共的数量  
  20.     private int totalGems;  
  21.   
  22.     //找到钻石的数量  
  23.     private int foundGems;  
  24.   
  25.     //游戏的状态  
  26.     private CrazyBallState gameSate;  
  27.   
  28.     void Awake()  
  29.     {  
  30.   
  31.   
  32.         CB = this;  
  33.         foundGems = 0;  
  34.         gameSate = CrazyBallState.playing;  
  35.   
  36.         totalGems = GameObject.FindGameObjectsWithTag ("Pickup").Length;  
  37.   
  38.         //开始游戏  
  39.         Time.timeScale = 1.0;  
  40.   
  41.     }  
  42.   
  43.   
  44.     void OnGUI()  
  45.     {  
  46.   
  47.   
  48.         GUI.skin.label = labelStyle;  
  49.   
  50.         GUI.skin.button = buttonStyle;  
  51.   
  52.         //显示找到的钻石数量  
  53.         GUILayout.Label ("Found gems:"+foundGems+"/"+totalGems);  
  54.   
  55.         if (gameSate == CrazyBallState.lost)  
  56.         {  
  57.           
  58.             //提示游戏失败  
  59.             GUILayout.Label("You Lost");  
  60.   
  61.             if(GUI.Button(new Rect(Screen.width/2,Screen.height/2,113,84),"Play again"))  
  62.             {  
  63.   
  64.                 //重新加载场景  
  65.                 Application.LoadLevel(Application.loadedLevel);  
  66.   
  67.   
  68.             }  
  69.   
  70.   
  71.         }  
  72.         else if(gameSate==CrazyBallState.won)  
  73.         {  
  74.             GUILayout.Label("You won");  
  75.   
  76.   
  77.             if(GUI.Button(new Rect(Screen.width/2,Screen.height/2,113,84),"Play again"))  
  78.             {  
  79.                   
  80.                 //重新加载场景  
  81.                 Application.LoadLevel(Application.loadedLevel);  
  82.                   
  83.                   
  84.             }  
  85.   
  86.         }  
  87.   
  88.     }  
  89.   
  90.   
  91.     public void FoundGem()  
  92.     {  
  93.   
  94.   
  95.         foundGems++;  
  96.         if(foundGems>=totalGems)  
  97.         {  
  98.   
  99.   
  100.             WonGame();  
  101.   
  102.   
  103.         }  
  104.   
  105.   
  106.   
  107.     }  
  108.   
  109.   
  110.     public void WonGame()  
  111.     {  
  112.   
  113.         //暂停游戏  
  114.         Time.timeScale = 0.0;  
  115.   
  116.   
  117.         gameSate = CrazyBallState.won;  
  118.   
  119.     }  
  120.   
  121.     public void SetGameOver()  
  122.     {  
  123.   
  124.         //暂停游戏  
  125.         Time.timeScale = 0.0;  
  126.   
  127.         gameSate = CrazyBallState.lost;  
  128.   
  129.     }  
  130.   
  131.   
  132. }  
CrayBallManager脚本文件中,每调用一次FoundGem()函数,对FoundGems变量累加一次,所以我们在BallControl.cs中修改如下代码:

[csharp]  view plain copy
  1. {  
  2.         //判断小球是否与钻石对象碰撞  
  3.         if (other.tag == "Pickup")  
  4.         {  
  5.                   
  6.   
  7.             CrazyBallManager.CB.FoundGem();  
  8.   
  9.             //销毁对象  
  10.             Destroy(other.gameObject);  
  11.           
  12.           
  13.           
  14.           
  15.         }  
  16.   
  17.   
  18.   
  19.   
  20.     }  

GameOverTrigger.cs修改如下:

[csharp]  view plain copy
  1. void OnTriggerEnter()  
  2.    {  
  3.          
  4.   
  5.     CrazyBallManager.CB.SetGameOver ();  
  6.     //  

将CrayBallManager.cs脚本绑定到Main Camera对象上,然后我们单击Main Camera对象,单击ButtonStyle属性,设置Background属性,放入一张图片,设置FontSize为18,Alignment为Middle Center,设置Fixed Width为113,Height为84,如下图:


运行游戏,如下图:


游戏中的摄像机并没有跟随小球,造成了游戏难以操作的现象,所以我新建一个脚本,叫BallCamera.cs,代码如下:

[csharp]  view plain copy
  1. using UnityEngine;  
  2. using System.Collections;  
  3.   
  4. public class BallCamera : MonoBehaviour  
  5. {  
  6.     //跟随的目标物体  
  7.     public Transform target;  
  8.     //与目标物体的相对高度  
  9.     public float relativeHeigth = 10.0f;  
  10.     //与目标物体的相对距离  
  11.     public float zDistance = 5.0f;  
  12.     //阻尼速度  
  13.     public float dampSpeed = 2;  
  14.   
  15.     void Update()  
  16.     {  
  17.   
  18.         Vector3 newPos = target.position + new Vector3(0, relativeHeigth, -zDistance);  
  19.         //像弹簧一样跟随目标物体  
  20.         transform.position = Vector3.Lerp(transform.position, newPos, Time.deltaTime * dampSpeed);  
  21.     }  
  22. }  
绑定到Main Camera对象上,target为ball对象,运行游戏,如下图:






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值