4 坦克移動和旋轉
本節課的目標是實現同時wsad和上下左右控制兩個坦克分別移動和旋轉
4.1 本節代碼預覽

將上節課場景s2另存為s3.
4.2 添加車輪揚沙效果
從Prefabs里面找到DustTrail,拖放到Tank里面

單擊DustTrail,改為LeftDustTrail,設置坐標為(-0.5,0,-0.75)
在Hierarchy里面使用快捷鍵Ctrl+D,復制LeftDustTrail,改為RightDustTrail,
設置坐標為(0.5,0,-0.75)
4.3 添加腳本
首先在Project面板中選中wm/Scripts文件夾,右鍵彈出新建菜單,選擇
Create->C# Script

將默認腳本名稱改為TankMove,注意大小寫.

實現坦克移動和旋轉有很多方法,這里介紹兩種:使用transform和rigidbody.
4.4 使用transform移動和旋轉(TankMove.cs)
TankMove.cs代碼如下:

Transform有Translate()方法實現位置的移動,Rotate()方法實現旋轉.
首先我們聲明兩個速度變量moveSpeed 和 turenSpeed
public float moveSpeed = 5; // 移動速度
public float turnSpeed = 90; // 旋轉速度
在Update() 里面循環執行移動和旋轉
void Update () {
transform.Translate (Vector3.forward * moveSpeed * Time.deltaTime);// 移動 transform.Rotate (transform.up * turnSpeed * Time.deltaTime);// 旋轉 }
完整代碼:
using UnityEngine;
using System.Collections;
public class TankMove : MonoBehaviour {
public float moveSpeed = 5; // 移動速度 public float turnSpeed = 90; // 旋轉速度 // Update is called once per frame void Update () { transform.Translate (Vector3.forward * moveSpeed * Time.deltaTime);// 移動 transform.Rotate (transform.up * turnSpeed * Time.deltaTime);// 旋轉 }
}
為坦克掛載TankMove腳本

運行游戲,就能看到坦克在原地繞圈.

4.5 使用rigidbody移動和旋轉(TankMoveRB.cs)

剛體有MovePosition方法可以實現剛體的移動,MoveRotation可以實現剛體的旋轉.
最終代碼如下:
using UnityEngine;
using System.Collections;
public class TankMoveRB : MonoBehaviour {
public float moveSpeed = 5; // 移動速度 public float turnSpeed = 90; // 旋轉速度( 每秒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); // 移動到新坐標 Quaternion turn = Quaternion.Euler (0, turnSpeed * Time.deltaTime, 0); rb.MoveRotation (rb.rotation * turn); // 旋轉到新角度 }
}
4.6 添加鍵盤控制
使用菜單打開Input設置


a/d對應Horizontal1,ws對應Vertical1

在Update里面獲取水平和垂直變量
private float moveInputValue = 0; // 移動輸入變量
private float turnInputValue = 0; // 旋轉輸入變量 void Update(){ moveInputValue = Input.GetAxis ("Vertical1"); turnInputValue = Input.GetAxis ("Horizontal"); }
然后將這兩個變量當成參數乘到移動速度和旋轉速度里面
Vector3 movement = transform.forward * moveSpeed * Time.deltaTime * moveInputValue ;
rb.MovePosition (transform.position + movement); // 移動到新坐標 Quaternion turn = Quaternion.Euler (0, turnSpeed * Time.deltaTime * turnInputValue , 0); rb.MoveRotation (rb.rotation * turn); // 旋轉到新角度
TankMoveByKeyboad.cs全部代碼:
using UnityEngine;
using System.Collections;
public class TankMoveByKeyboard : MonoBehaviour {
public float turnSpeed = 180; // 旋轉速度( 每秒180度) public float moveSpeed = 15; // 移動速度 private float moveInputValue = 0; // 移動輸入變量 private float turnInputValue = 0; // 旋轉輸入變量 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); // 移動到新坐標 Quaternion turn = Quaternion.Euler (0, turnSpeed * Time.deltaTime * turnInputValue , 0); rb.MoveRotation (rb.rotation * turn); // 旋轉到新角度 }
}
4.7 區分坦克
將坦克的掛載TankMoveByKeyboard腳本,去掉其他腳本.

點擊Prefab最右邊的Apply保存預設體.
然后從wm/prefabs中拖放Tank到Hierarchy里面
改為Tank2,設置坐標為(5,0,0)

這時候我們有了兩個Tank,點擊運行.
然后我們會發現這時候兩個Tank是一起運動和旋轉的.

而我們最終實現的效果應該是兩個坦克分別控制的,這時候我們再來看一下Input的設置

里面專門為兩個坦克設置了不同的Axis,以1和2作為區分,那么問題來了,如何利用這一點呢?
這時候我們就要想到我們現在的腳本里是寫死了Axis的,現在只需要能隨意更改1或者2就可以了.

所以這時候我們就需要聲明一個變量id來區別到底是哪個坦克.

這樣我們就把兩個坦克區分開了.
下面是TankMoveByKeyboard2.cs的完整代碼:
using UnityEngine;
using System.Collections;
public class TankMoveByKeyboard2 : MonoBehaviour {
public float turnSpeed = 180; // 旋轉速度( 每秒180度) public float moveSpeed = 15; // 移動速度 private Rigidbody rb ; // 剛體組件 private float moveInputValue = 0; // 移動輸入變量 private float turnInputValue = 0; // 旋轉輸入變量 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); // 移動到新坐標 Quaternion turn = Quaternion.Euler (0, turnSpeed * Time.deltaTime * turnInputValue , 0); rb.MoveRotation (rb.rotation * turn); // 旋轉到新角度 }
}
將Tank上掛載的腳步更改為TankMoveByKeyboard2 ,Apply prefab.
Tank id設置為1,Tank2id設置為2


這時候我們就實現了兩個坦克的分別控制
本節內容到此結束,希望通過本節內容大家可以加深對於變量的理解和應用.
---------------------------我是目錄分割線---------------------------
《杜增強講Unity之Tanks坦克大戰》4-坦克的移動和旋轉
《杜增強講Unity之Tanks坦克大戰》9-發射子彈時蓄力
《杜增強講Unity之Tanks坦克大戰》11-游戲流程控制
---------------------------我是目錄分割線---------------------------