這次我們做一個打箱子的小項目,不是推箱子= = 忍疾。目標是實現(xiàn)自動生成一堵由箱子(Cube)組成的墻蹈集,然后鼠標對準箱子按下左鍵會蓄力闺兢,松開后生成一個子彈(Sphere)射向瞄準的箱子。
首先我們創(chuàng)建一個Scene場景帽揪,場景中有一個地面(Plane)和一個空物體(Box硝清,用來做箱子-Cube的父級),如圖:
然后我們在腳本中用代碼實現(xiàn)自動創(chuàng)造一堵墻转晰,代碼如下:
public GameObject box;//獲取我們Scene中的Box空物體
void Start () {
//創(chuàng)造墻的代碼寫在Start方法中芦拿,因為游戲一運行就會有一堵墻
for (int i = 0; i < 18; i++)
{
for (int j = 0; j < 10; j++)
{
GameObject go = GameObject.CreatePrimitive(PrimitiveType.Cube);//創(chuàng)造物體Cube做為箱子
go.transform.localScale = new Vector3(5,5,5);//設置箱子大小
go.transform.position = new Vector3(-45+i*5,2.5f+j*5,38);//-45和38是根據(jù)我的場景位置設置的,i和j分別用來確定箱子的x查邢,y位置
go.transform.parent = box.transform;//把每一個創(chuàng)造的箱子都變成Box的子級
go.GetComponent<Renderer>().material.color= new Color(Random.Range(0f, 1f), Random.Range(0f, 1f), Random.Range(0f, 1f));//給箱子加上隨機顏色
go.AddComponent<Rigidbody>();//給箱子加上剛體組件
go.tag = "Player";//把箱子的tag值設置為Player(在這之前要確保你的Tag里面有Player防嗡,否則需要先創(chuàng)造一個名為Player的tag值)
}
}
}
如圖是如何創(chuàng)建一個新的Tag值:
運行項目,得到如圖所示效果:
接下來我們就需要用鼠標進行交互侠坎,自動生成子彈(Sphere)蚁趁,并射向瞄準的箱子,代碼如下:
private Vector3 offset;//目標位置和相機位置的向量实胸,也就是子彈射向的方向
void Update () {
if (Input.GetMouseButtonDown(0))//按一下鼠標左鍵(此時射擊像手槍他嫡,單擊一下射一發(fā);如果是GetMouseButton就會像機關槍庐完,按住不動一直射)钢属,其中0表示鼠標左鍵,1是右鍵
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);//射線檢測门躯,從主相機發(fā)射一條射線到鼠標點擊的位置(該腳本就是掛在主相機上面)淆党,返回該射線
RaycastHit hit;//聲明一個RaycastHit,有點類似Collision,自行進行對比 = =
if (Physics.Raycast(ray, out hit))
{
if (hit.collider.tag == "Player")//判斷鼠標點擊的物體是不是箱子
{
GameObject gb = GameObject.CreatePrimitive(PrimitiveType.Sphere);//生成子彈
gb.GetComponent<Renderer>().material.color = new Color(Random.Range(0f, 1f), Random.Range(0f, 1f), Random.Range(0f, 1f));//給子彈隨機顏色
gb.transform.localScale = new Vector3(1,1,1);//設置子彈大小
gb.transform.position = transform.position;//設置子彈的初始位置為主相機的位置
offset = hit.transform.position - transform.position;//獲取子彈要射向的方向
gb.AddComponent<Rigidbody>().AddForce(offset*50);//給子彈加剛體讶凉,并給一個力(乘以50是讓子彈飛的快)
gb.GetComponent<Rigidbody>().collisionDetectionMode = CollisionDetectionMode.Continuous;//因為子彈速度如果太快會穿過箱子或者地面染乌,這時就需要設置一下剛體中的collisionDetectionMode屬性,這在剛體中講過懂讯,不再敘述
Destroy(gb,2f);//2秒后銷毀子彈荷憋,因為子彈創(chuàng)造太多會消耗性能
}
}
}
}
運行效果如圖:
下面我們再進行一些改進:把鼠標樣式改成一個瞄準星,按下鼠標左鍵就開始蓄力褐望,蓄力越久勒庄,子彈速度越大串前,子彈碰撞到箱子時產(chǎn)生特效。
更改后的代碼如下(鼠標按下發(fā)射子彈的方法改成鼠標松開發(fā)射实蔽,):
public GameObject box;//獲取我們Scene中的Box空物體
private Vector3 offset;//目標位置和相機位置的向量荡碾,也就是子彈射向的方向
public Texture2D pic;//力度條圖片
public Texture2D mousepic;//要代替鼠標的圖片,是一個瞄準星圖片
private float width;//需要繪制的蓄力條長度
private float forcetime = 3f;//設定蓄力時間最多3秒
private float timer;//蓄力時間差值
private float t = 0;//開始蓄力的時間點為0秒局装;
private bool isui=false;//判斷是否開始繪制蓄力條
void Start () {
//Cursor.visible = false;
//創(chuàng)造墻的代碼寫在Start方法中玩荠,因為游戲一運行就會有一堵墻
for (int i = 0; i < 18; i++)
{
for (int j = 0; j < 10; j++)
{
GameObject go = GameObject.CreatePrimitive(PrimitiveType.Cube);//創(chuàng)造物體Cube做為箱子
go.transform.localScale = new Vector3(5,5,5);//設置箱子大小
go.transform.position = new Vector3(-45+i*5,2.5f+j*5,38);//-45和38是根據(jù)我的場景位置設置的,i和j分別用來確定箱子的x贼邓,y位置
go.transform.parent = box.transform;//把每一個創(chuàng)造的箱子都變成Box的子級
go.GetComponent<Renderer>().material.color= new Color(Random.Range(0f, 1f), Random.Range(0f, 1f), Random.Range(0f, 1f));//給箱子加上隨機顏色
go.AddComponent<Rigidbody>();//給箱子加上剛體組件
go.tag = "Player";//把箱子的tag值設置為Player(在這之前要確保你的Tag里面有Player阶冈,否則需要先創(chuàng)造一個名為Player的tag值)
}
}
}
void Update () {
if (Input.GetMouseButtonUp(0))//按一下鼠標左鍵(此時射擊像手槍,單擊一下射一發(fā)塑径;如果是GetMouseButton就會像機關槍女坑,按住不動一直射),其中0表示鼠標左鍵统舀,1是右鍵
{
isui = false;//鼠標抬起后不再繪制蓄力條
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);//射線檢測匆骗,從主相機發(fā)射一條射線到鼠標點擊的位置(該腳本就是掛在主相機上面),返回該射線
RaycastHit hit;//聲明一個RaycastHit,有點類似Collision誉简,自行進行對比 = =
if (Physics.Raycast(ray, out hit))
{
if (hit.collider.tag == "Player")//判斷鼠標點擊的物體是不是箱子
{
GameObject gb = GameObject.CreatePrimitive(PrimitiveType.Sphere);//生成子彈
gb.GetComponent<Renderer>().material.color = new Color(Random.Range(0f, 1f), Random.Range(0f, 1f), Random.Range(0f, 1f));//給子彈隨機顏色
gb.transform.localScale = new Vector3(1, 1, 1);//設置子彈大小
gb.transform.position = transform.position;//設置子彈的初始位置為主相機的位置
offset = hit.transform.position - transform.position;//獲取子彈要射向的方向
gb.AddComponent<Rigidbody>().AddForce(offset * 50f*(forcetime-timer));//給子彈加剛體碉就,并給一個力(乘以50是讓子彈飛的快),
gb.GetComponent<Rigidbody>().collisionDetectionMode = CollisionDetectionMode.Continuous;//因為子彈速度如果太快會穿過箱子或者地面闷串,這時就需要設置一下剛體中的collisionDetectionMode屬性瓮钥,這在剛體中講過,不再敘述
Destroy(gb, 2f);//2秒后銷毀子彈烹吵,因為子彈創(chuàng)造太多會消耗性能
}
}
}
if (Input.GetMouseButtonDown(0))
{
isui = true;//鼠標左鍵按下開始繪制蓄力條
t = 0;//重置開始蓄力的時間點為0秒碉熄;
}
}
void OnGUI()
{
Cursor.SetCursor(mousepic, new Vector2(mousepic.width/2,mousepic.height/2), CursorMode.Auto);//用系統(tǒng)自帶的方法更換鼠標圖片,圖片格式必須是Cursor
//Vector2 mouse_Pos = Input.mousePosition;//獲取鼠標點擊位置
//GUI.DrawTexture(new Rect(mouse_Pos.x-15, Screen.height - mouse_Pos.y-15, 30, 30), mousepic); //自己繪制鼠標圖片肋拔,圖片的大小可以自己設置锈津;
if (isui)
{
t += Time.deltaTime;//計時
timer = Mathf.Clamp((forcetime - t),0f,3f);//該方法獲得蓄力時間差值
width = pic.width - timer/forcetime*pic.width;//計算出需要繪制的蓄力條長度
GUI.DrawTexture(new Rect(530f, 20f, width, pic.height), pic);//繪制蓄力條
}
}