《Unity入門案例-Tanks坦克大戰(zhàn)》4-坦克的移動(dòng)和旋轉(zhuǎn)

4 坦克移動(dòng)和旋轉(zhuǎn)

本節(jié)課的目標(biāo)是實(shí)現(xiàn)同時(shí)wsad和上下左右控制兩個(gè)坦克分別移動(dòng)和旋轉(zhuǎn)

4.1 本節(jié)代碼預(yù)覽

image

將上節(jié)課場景s2另存為s3.

4.2 添加車輪揚(yáng)沙效果

從Prefabs里面找到DustTrail,拖放到Tank里面

image

單擊DustTrail,改為LeftDustTrail,設(shè)置坐標(biāo)為(-0.5,0,-0.75)

在Hierarchy里面使用快捷鍵Ctrl+D,復(fù)制LeftDustTrail,改為RightDustTrail,

設(shè)置坐標(biāo)為(0.5,0,-0.75)

4.3 添加腳本

首先在Project面板中選中wm/Scripts文件夾,右鍵彈出新建菜單,選擇

Create->C# Script

image

將默認(rèn)腳本名稱改為TankMove,注意大小寫.

image

實(shí)現(xiàn)坦克移動(dòng)和旋轉(zhuǎn)有很多方法,這里介紹兩種:使用transform和rigidbody.

4.4 使用transform移動(dòng)和旋轉(zhuǎn)(TankMove.cs)

TankMove.cs代碼如下:

image

Transform有Translate()方法實(shí)現(xiàn)位置的移動(dòng),Rotate()方法實(shí)現(xiàn)旋轉(zhuǎn).

首先我們聲明兩個(gè)速度變量moveSpeed 和 turenSpeed

public float moveSpeed = 5; // 移動(dòng)速度

public float turnSpeed = 90; // 旋轉(zhuǎn)速度

在Update() 里面循環(huán)執(zhí)行移動(dòng)和旋轉(zhuǎn)

void Update () {

    transform.Translate (Vector3.forward * moveSpeed * Time.deltaTime);// 移動(dòng)

    transform.Rotate (transform.up * turnSpeed * Time.deltaTime);// 旋轉(zhuǎn)

}

完整代碼:

using UnityEngine;

using System.Collections;

public class TankMove : MonoBehaviour {

public float moveSpeed = 5; // 移動(dòng)速度

public float turnSpeed = 90; // 旋轉(zhuǎn)速度

// Update is called once per frame

void Update () {       

    transform.Translate (Vector3.forward * moveSpeed * Time.deltaTime);// 移動(dòng)

    transform.Rotate (transform.up * turnSpeed * Time.deltaTime);// 旋轉(zhuǎn)

}       

}

為坦克掛載TankMove腳本

image

運(yùn)行游戲,就能看到坦克在原地繞圈.

image

4.5 使用rigidbody移動(dòng)和旋轉(zhuǎn)(TankMoveRB.cs)

image

剛體有MovePosition方法可以實(shí)現(xiàn)剛體的移動(dòng),MoveRotation可以實(shí)現(xiàn)剛體的旋轉(zhuǎn).

最終代碼如下:

using UnityEngine;

using System.Collections;

public class TankMoveRB : MonoBehaviour {

public float moveSpeed = 5; // 移動(dòng)速度

public float turnSpeed = 90; // 旋轉(zhuǎn)速度( 每秒90度)

private Rigidbody rb ; // 剛體組件

// Use this for initialization

void Start () {

    rb = GetComponent<Rigidbody> (); // 獲取剛體組件

}

// Update is called once per frame

void FixedUpdate () {

    Vector3 movement = transform.forward * moveSpeed * Time.deltaTime;

    rb.MovePosition (transform.position + movement); // 移動(dòng)到新坐標(biāo)

    Quaternion turn = Quaternion.Euler (0, turnSpeed * Time.deltaTime, 0);

    rb.MoveRotation (rb.rotation * turn); // 旋轉(zhuǎn)到新角度

}

}

4.6 添加鍵盤控制

使用菜單打開Input設(shè)置

image
image

a/d對(duì)應(yīng)Horizontal1,ws對(duì)應(yīng)Vertical1

image

在Update里面獲取水平和垂直變量

private float moveInputValue = 0; // 移動(dòng)輸入變量

private float turnInputValue = 0; // 旋轉(zhuǎn)輸入變量

void Update(){

    moveInputValue = Input.GetAxis ("Vertical1");

    turnInputValue = Input.GetAxis ("Horizontal");   

}

然后將這兩個(gè)變量當(dāng)成參數(shù)乘到移動(dòng)速度和旋轉(zhuǎn)速度里面

Vector3 movement = transform.forward * moveSpeed * Time.deltaTime * moveInputValue ;

    rb.MovePosition (transform.position + movement); // 移動(dòng)到新坐標(biāo)

    Quaternion turn = Quaternion.Euler (0, turnSpeed * Time.deltaTime * turnInputValue , 0);

    rb.MoveRotation (rb.rotation * turn); // 旋轉(zhuǎn)到新角度

TankMoveByKeyboad.cs全部代碼:

using UnityEngine;

using System.Collections;

public class TankMoveByKeyboard : MonoBehaviour {

public float turnSpeed = 180; // 旋轉(zhuǎn)速度( 每秒180度)

public float moveSpeed = 15; // 移動(dòng)速度

private float moveInputValue = 0; // 移動(dòng)輸入變量

private float turnInputValue = 0; // 旋轉(zhuǎn)輸入變量

private Rigidbody rb ; // 剛體組件

// Use this for initialization

void Start () {

    rb = GetComponent<Rigidbody> (); // 獲取剛體組件

}

// Update is called once per frame

void Update(){

    moveInputValue = Input.GetAxis ("Vertical1");

    turnInputValue = Input.GetAxis ("Horizontal1");   

}

// Update is called once per frame

void FixedUpdate () {

    Vector3 movement = transform.forward * moveSpeed * Time.deltaTime * moveInputValue ;

    rb.MovePosition (transform.position + movement); // 移動(dòng)到新坐標(biāo)

    Quaternion turn = Quaternion.Euler (0, turnSpeed * Time.deltaTime * turnInputValue , 0);

    rb.MoveRotation (rb.rotation * turn); // 旋轉(zhuǎn)到新角度

}

}

4.7 區(qū)分坦克

將坦克的掛載TankMoveByKeyboard腳本,去掉其他腳本.

image

點(diǎn)擊Prefab最右邊的Apply保存預(yù)設(shè)體.

然后從wm/prefabs中拖放Tank到Hierarchy里面

改為Tank2,設(shè)置坐標(biāo)為(5,0,0)

image

這時(shí)候我們有了兩個(gè)Tank,點(diǎn)擊運(yùn)行.

然后我們會(huì)發(fā)現(xiàn)這時(shí)候兩個(gè)Tank是一起運(yùn)動(dòng)和旋轉(zhuǎn)的.

image

而我們最終實(shí)現(xiàn)的效果應(yīng)該是兩個(gè)坦克分別控制的,這時(shí)候我們再來看一下Input的設(shè)置

image

里面專門為兩個(gè)坦克設(shè)置了不同的Axis,以1和2作為區(qū)分,那么問題來了,如何利用這一點(diǎn)呢?

這時(shí)候我們就要想到我們現(xiàn)在的腳本里是寫死了Axis的,現(xiàn)在只需要能隨意更改1或者2就可以了.

image

所以這時(shí)候我們就需要聲明一個(gè)變量id來區(qū)別到底是哪個(gè)坦克.

image

這樣我們就把兩個(gè)坦克區(qū)分開了.

下面是TankMoveByKeyboard2.cs的完整代碼:

using UnityEngine;

using System.Collections;

public class TankMoveByKeyboard2 : MonoBehaviour {

public float turnSpeed = 180; // 旋轉(zhuǎn)速度( 每秒180度)

public float moveSpeed = 15; // 移動(dòng)速度

private Rigidbody rb ; // 剛體組件

private float moveInputValue = 0; // 移動(dòng)輸入變量

private float turnInputValue = 0; // 旋轉(zhuǎn)輸入變量

public int id = 1; // tank id

// Use this for initialization

void Start () {

    rb = GetComponent<Rigidbody> (); // 獲取剛體組件

}

void Update(){

    moveInputValue = Input.GetAxis ("Vertical" + id);

    turnInputValue = Input.GetAxis ("Horizontal" + id);   

}

// Update is called once per frame

void FixedUpdate () {

    Vector3 movement = transform.forward * moveSpeed * Time.deltaTime * moveInputValue ;

    rb.MovePosition (transform.position + movement); // 移動(dòng)到新坐標(biāo)

    Quaternion turn = Quaternion.Euler (0, turnSpeed * Time.deltaTime * turnInputValue , 0);

    rb.MoveRotation (rb.rotation * turn); // 旋轉(zhuǎn)到新角度

}

}

將Tank上掛載的腳步更改為TankMoveByKeyboard2 ,Apply prefab.

Tank id設(shè)置為1,Tank2id設(shè)置為2

image
image

這時(shí)候我們就實(shí)現(xiàn)了兩個(gè)坦克的分別控制

本節(jié)內(nèi)容到此結(jié)束,希望通過本節(jié)內(nèi)容大家可以加深對(duì)于變量的理解和應(yīng)用.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容