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

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

unity3D游戏开发十二之疯狂的小球_第1张图片

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

unity3D游戏开发十二之疯狂的小球_第2张图片

选择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),如下图:

unity3D游戏开发十二之疯狂的小球_第3张图片

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

unity3D游戏开发十二之疯狂的小球_第4张图片

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

unity3D游戏开发十二之疯狂的小球_第5张图片

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

unity3D游戏开发十二之疯狂的小球_第6张图片

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

using UnityEngine;
using System.Collections;

public class BallControl : MonoBehaviour {

	//小球运动的速率
	public float movementSpeed=6.0f; 
	//小球的水平运动
	private Vector3 horizontalMovement;
	//小球的前后运动
	private Vector3 verticalMovement;


	// Use this for initialization
	void Start ()
	{




	
	}
	
	// Update is called once per frame
	void Update () 
	{

		//Vector3.right x zhou
		horizontalMovement=Input.GetAxis("Horizontal")*Vector3.right*movementSpeed;
		
		//z zhou
		verticalMovement=Input.GetAxis("Vertical")*Vector3.forward*movementSpeed;
		
		//小球的运动
		Vector3 movement=horizontalMovement+verticalMovement;
		
		//为小球施加力
		rigidbody.AddForce(movement,ForceMode.Force);

	
	}
}
然后绑定到Ball对象上,如下图:


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

unity3D游戏开发十二之疯狂的小球_第7张图片

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

unity3D游戏开发十二之疯狂的小球_第8张图片

依次设置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对象,设好后如下图:

unity3D游戏开发十二之疯狂的小球_第9张图片

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

void OnTriggerEnter(Collider other)
	{
		//判断小球是否与钻石对象碰撞
		if (other.tag == "Pickup")
		{
				
			//销毁对象
			Destroy(other.gameObject);
		
		
		
		
		}




	}

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

unity3D游戏开发十二之疯狂的小球_第10张图片

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

using UnityEngine;
using System.Collections;

public class GameOverTrigger : MonoBehaviour {

    void OnTriggerEnter()
    {
        

		Debug.Log("over");
    }
}

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

using UnityEngine;
using System.Collections;

//枚举
public enum CrazyBallState { playing, won, lost };

public class CrazyBallManager : MonoBehaviour
{	

	//单例
	public static CrazyBallManager CB;

	//按钮
	public GUIStyle buttonStyle;

	//标签
	public GUIStyle labelStyle;

	//钻石总共的数量
	private int totalGems;

	//找到钻石的数量
	private int foundGems;

	//游戏的状态
	private CrazyBallState gameSate;

	void Awake()
	{


		CB = this;
		foundGems = 0;
		gameSate = CrazyBallState.playing;

		totalGems = GameObject.FindGameObjectsWithTag ("Pickup").Length;

		//开始游戏
		Time.timeScale = 1.0;

	}


	void OnGUI()
	{


		GUI.skin.label = labelStyle;

		GUI.skin.button = buttonStyle;

		//显示找到的钻石数量
		GUILayout.Label ("Found gems:"+foundGems+"/"+totalGems);

		if (gameSate == CrazyBallState.lost)
		{
		
			//提示游戏失败
			GUILayout.Label("You Lost");

			if(GUI.Button(new Rect(Screen.width/2,Screen.height/2,113,84),"Play again"))
			{

				//重新加载场景
				Application.LoadLevel(Application.loadedLevel);


			}


		}
		else if(gameSate==CrazyBallState.won)
		{
			GUILayout.Label("You won");


			if(GUI.Button(new Rect(Screen.width/2,Screen.height/2,113,84),"Play again"))
			{
				
				//重新加载场景
				Application.LoadLevel(Application.loadedLevel);
				
				
			}

		}

	}


	public void FoundGem()
	{


		foundGems++;
		if(foundGems>=totalGems)
		{


			WonGame();


		}



	}


	public void WonGame()
	{

		//暂停游戏
		Time.timeScale = 0.0;


		gameSate = CrazyBallState.won;

	}

	public void SetGameOver()
	{

		//暂停游戏
		Time.timeScale = 0.0;

		gameSate = CrazyBallState.lost;

	}


}
CrayBallManager脚本文件中,每调用一次FoundGem()函数,对FoundGems变量累加一次,所以我们在BallControl.cs中修改如下代码:

{
		//判断小球是否与钻石对象碰撞
		if (other.tag == "Pickup")
		{
				

			CrazyBallManager.CB.FoundGem();

			//销毁对象
			Destroy(other.gameObject);
		
		
		
		
		}




	}

GameOverTrigger.cs修改如下:

 void OnTriggerEnter()
    {
        

		CrazyBallManager.CB.SetGameOver ();
		//

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

unity3D游戏开发十二之疯狂的小球_第11张图片

运行游戏,如下图:

unity3D游戏开发十二之疯狂的小球_第12张图片

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

using UnityEngine;
using System.Collections;

public class BallCamera : MonoBehaviour
{
	//跟随的目标物体
    public Transform target;
	//与目标物体的相对高度
    public float relativeHeigth = 10.0f;
	//与目标物体的相对距离
    public float zDistance = 5.0f;
	//阻尼速度
    public float dampSpeed = 2;

    void Update()
    {

        Vector3 newPos = target.position + new Vector3(0, relativeHeigth, -zDistance);
		//像弹簧一样跟随目标物体
        transform.position = Vector3.Lerp(transform.position, newPos, Time.deltaTime * dampSpeed);
    }
}
绑定到Main Camera对象上,target为ball对象,运行游戏,如下图:

unity3D游戏开发十二之疯狂的小球_第13张图片



unity3D游戏开发十二之疯狂的小球_第14张图片



你可能感兴趣的:(unity3d,游戏开发,物理引擎,小球)