實作效果:
點選 “w” 鍵,坦克前進,點選 “s” 鍵,坦克後退,點選 “a” 鍵,坦克向左轉,點選 “d” 鍵,坦克向右轉。
點選 “空格” 鍵,坦克發射炮彈(這裡的炮彈是一棵樹),當炮彈碰到物體時,物體和炮彈都消失。
當坦克走近關卡時,關卡自動打開,當坦克遠離關卡時,關卡自動閉合。
制作過程
坦克前後左右移動、發射炮彈:
- 添加一個坦克
- 為坦克添加 BoxCollider,Rigidbody 元件
- 建立 C# 腳本,腳本名為 TankController ,并将該腳本賦給坦克,腳本内容如下
- 為坦克添加一個 Sphere 圓柱體(坦克為父元件,圓柱體為子元件),為圓柱體添加 BoxCollider 元件。圓柱體的作用是标志炮彈發射的位置,為了視覺效果可以将圓柱體隐藏起來,即在屬性中将 Mesh Renderer 前的勾去掉。
- 制作一個預制體,作為發射的炮彈,這裡命名為 palm_01
- 為腳本中的共有變量指派,speed:坦克前後移動時每秒移動的距離 rotspeed:坦克左右轉動時每秒移動的距離 bullet:要發射的炮彈,将預制體palm_01拖動到這裡 bulletspeed:炮彈發射速度 firePos:标志炮彈發射位置的物體,将第四步中的Sphere圓柱體拖動到此處。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TankController : MonoBehaviour
{
public int speed;//坦克前後移動時每秒移動的距離
public float rotspeed;//坦克左右轉動時每秒移動的距離
public GameObject bullet;//聲明遊戲對象:要發射的炮彈
public int bulletspeed; //炮彈發射速度
public Transform firePos; //标志炮彈發射位置的物體
private Transform t;
// Start is called before the first frame update
void Start()
{
t = this.GetComponent<Transform>(); //擷取本身和所有子子物體
}
void move1()
{ //實作前後左右移動的第一種方法,這裡将他們封裝在這個move1()函數裡,并沒有起到實際用。
if (Input.GetKey(KeyCode.W)) //當按下W鍵時,坦克向前移動
{
//通過Translate()這個方法可以使得物體移動,裡面有Vector3,(Vector3是一個三維向量,在unity中用于傳遞3D位置和方向),
//通過在後面加入Time.deltaTime來使得物體移動更加的平滑。
//裡面還有一個Space.Self,它代表着以自身坐标系來移動,與之相對的還有Space.World,代表着是以世界坐标系來移動的。
t.Translate(t.forward * Time.deltaTime * -speed, Space.World);
}
if (Input.GetKey(KeyCode.S))//當按下S鍵時,坦克向後移動
{
t.Translate(t.forward * Time.deltaTime * speed, Space.World);
}
if (Input.GetKey(KeyCode.A))//當按下A鍵時,坦克向右旋轉
{
//使用localEulerAngles進行旋轉的時候,我們要使用transform.localEulerAngles = new Vector3(x, y,z);
//其中,new Vector(x,y,z)為遊戲物體最終旋轉到的目标角度,x.y,z的值分别都是以0為基準,假設遊戲物體的初始角度為(x1,y1,z1),
//則遊戲物體從(x1,y1,z1)旋轉到(x,y,z),同時也以自身坐标系為參考,而不是世界坐标系。
t.localEulerAngles += new Vector3(0, 1 * rotspeed, 0);
}
if (Input.GetKey(KeyCode.D))//當按下D鍵時,坦克向左旋轉
{
t.localEulerAngles -= new Vector3(0, 1 * rotspeed, 0);
}
}
// Update is called once per frame
void Update()
{
//實作前後左右移動的第二種方法
float v = Input.GetAxis("Vertical"); //擷取輸入裝置中所有垂直方向的偏移。範圍(-1,1)
float h = Input.GetAxis("Horizontal"); //擷取輸入裝置中所有水準方向的偏移。範圍(-1,1)
Vector3 moveDir = new Vector3(h, 0, v);
if (h!=0) //當水準方向的偏移不為0時發生旋轉,排除垂直方向(即前後移動)的影響
{
Quaternion qua = Quaternion.LookRotation(moveDir); //求出目前物體的方向與即将移動到的方向moveDir的夾角
transform.rotation = Quaternion.Lerp(transform.rotation, qua, Time.deltaTime * rotspeed);
//緩慢旋轉,第一個參數,從哪個角度開始轉;第二個參數,要旋轉的角度,第三個參數,旋轉速度
}
transform.Translate(transform.forward * v * Time.deltaTime * -speed, Space.World); //前後移動
if (Input.GetKeyDown(KeyCode.Space))//當按下空格鍵時,坦克發射炮彈
{
GameObject obj = Instantiate(bullet, firePos.position , bullet.transform.rotation);
//bullet:生成對象 firePos.position :生成位置 bullet.transform.rotation:以什麼角度生成。
Rigidbody rig = obj.AddComponent<Rigidbody>(); //為生成的炮彈對象添加剛體元件:Rigidbody,便于檢測它和物體發生碰撞
rig.AddForce(transform.forward * -1 * bulletspeed);//為生成的炮彈對象添加初始的速度矢量
}
}
}
自動門開關:
- 從資源包中找到自動門,添加一個到畫面中
- 為自動門添加 BoxCollider元件
- 在屬性中将 Is Trigger 勾選上
- 建立 C# 腳本,腳本名為 Door ,并将該腳本賦給自動門,腳本内容如下
- 為腳本中的共有變量指派:在自動門下找到名為 pole 的子元件(即自動門的那根開關),将它賦給共有變量 D
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Door : MonoBehaviour
{
public Transform d;//這裡将自動門的開關賦給d,以實作開關的旋轉
// Start is called before the first frame update
void Start()
{
}
void OnTriggerEnter(Collider c)//在腳本中添加這個函數,如果發生碰撞則執行此函數。(相撞的物體至少有一個勾選了isTrigger)
{
//當小車與自動門發生碰撞時,開關打開。
d.localEulerAngles = new Vector3(0, 90, 0);
}
void OnTriggerExit(Collider c)//在腳本中添加這個函數,如果碰撞結束則執行此函數。(相撞的物體至少有一個勾選了isTrigger)
{
//當小車與自動門發生碰撞時,開關合上。
d.localEulerAngles = new Vector3(0, 0, 0);
}
// Update is called once per frame
void Update()
{
}
}
碰撞後物體消失:
- 随便添加一個物體到畫面中,作為炮彈的打擊對象,這裡添加的是一輛醫用軍車
- 為該物體添加 BoxCollider元件
- 建立 C# 腳本,腳本名為 Bullet,腳本内容如下
- 将該腳本賦給炮彈的預制體
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Bullet : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
void OnCollisionEnter(Collision other)
//在腳本中添加這個函數,如果發生碰撞則執行此函數。other為與添加了此代碼的物體相撞的另一個物體
{
Destroy(other.gameObject);//消滅另一個物體
Destroy(this.gameObject);//消滅這個物體
}
// Update is called once per frame
void Update()
{
}
}
PS:如需完整項目,請移步 https://download.csdn.net/download/qq_42185999/11884672 進行下載下傳(項目中包含所用全部資源包)。