4 坦克移動(dòng)和旋轉(zhuǎn)
本節(jié)課的目標(biāo)是實(shí)現(xiàn)同時(shí)wsad和上下左右控制兩個(gè)坦克分別移動(dòng)和旋轉(zhuǎn)
4.1 本節(jié)代碼預(yù)覽
將上節(jié)課場景s2另存為s3.
4.2 添加車輪揚(yáng)沙效果
從Prefabs里面找到DustTrail,拖放到Tank里面
單擊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
將默認(rèn)腳本名稱改為TankMove,注意大小寫.
實(shí)現(xiàn)坦克移動(dòng)和旋轉(zhuǎn)有很多方法,這里介紹兩種:使用transform和rigidbody.
4.4 使用transform移動(dòng)和旋轉(zhuǎn)(TankMove.cs)
TankMove.cs代碼如下:
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腳本
運(yùn)行游戲,就能看到坦克在原地繞圈.
4.5 使用rigidbody移動(dòng)和旋轉(zhuǎn)(TankMoveRB.cs)
剛體有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è)置
a/d對(duì)應(yīng)Horizontal1,ws對(duì)應(yīng)Vertical1
在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腳本,去掉其他腳本.
點(diǎn)擊Prefab最右邊的Apply保存預(yù)設(shè)體.
然后從wm/prefabs中拖放Tank到Hierarchy里面
改為Tank2,設(shè)置坐標(biāo)為(5,0,0)
這時(shí)候我們有了兩個(gè)Tank,點(diǎn)擊運(yùn)行.
然后我們會(huì)發(fā)現(xiàn)這時(shí)候兩個(gè)Tank是一起運(yùn)動(dòng)和旋轉(zhuǎn)的.
而我們最終實(shí)現(xiàn)的效果應(yīng)該是兩個(gè)坦克分別控制的,這時(shí)候我們再來看一下Input的設(shè)置
里面專門為兩個(gè)坦克設(shè)置了不同的Axis,以1和2作為區(qū)分,那么問題來了,如何利用這一點(diǎn)呢?
這時(shí)候我們就要想到我們現(xiàn)在的腳本里是寫死了Axis的,現(xiàn)在只需要能隨意更改1或者2就可以了.
所以這時(shí)候我們就需要聲明一個(gè)變量id來區(qū)別到底是哪個(gè)坦克.
這樣我們就把兩個(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
這時(shí)候我們就實(shí)現(xiàn)了兩個(gè)坦克的分別控制
本節(jié)內(nèi)容到此結(jié)束,希望通過本節(jié)內(nèi)容大家可以加深對(duì)于變量的理解和應(yīng)用.