上一篇文章介紹了使用unity3D進行戰斗機飛行模擬的設計http://www.cnblogs.com/jqg-aliang/p/4598515.html,其實只要稍微修改一下,就變成了直升機的飛行模擬。只需要復寫一下幾個移動的方法就行了。
需要寫的功能如下:直升機的前進,后退,左右移動,左右旋轉,升高和降落
還是以數學模擬為例,我們需要幾個值來控制游戲對象(直升機)的移動效果。具體參數的我就不說了,直接上代碼吧。
using UnityEngine; using System.Collections; public class GameHelicopter : Flight { //這個是直升機的算法實現 //需要寫的功能如下:直升機的前進,后退,左右移動,左右旋轉,升降,
bool IsFBB = false, IsLRB = false; //private float downSpeed; private float currentUDSpeed; private float currentMLRSpeed; private float currentRLRSpeed; public override void MoveFB(float speed) { if ((IsSing) || IsOnGround) return; CurrentSpeed += speed * aircaft.Acc * Time.deltaTime; CurrentSpeed = Mathf.Clamp(CurrentSpeed, aircaft.MinSpeed, aircaft.MaxSpeed); if ((IsSing) || IsOnGround) return; IsFBB = false; Balance(Quaternion.Euler(aircaft.AxisFB * speed, body.eulerAngles.y, body.eulerAngles.z), aircaft.RoteFBSpeed * Time.deltaTime/5); } public override void MoveLR(float speed) { //左右移動 if ((IsSing) || IsOnGround) return; //IsLRB = false; currentMLRSpeed += speed * Time.deltaTime * aircaft.Acc; currentMLRSpeed = Mathf.Clamp(currentMLRSpeed, -aircaft.MoveLRSpeed, aircaft.MoveLRSpeed); /*Vector3 vector = body.right; vector.y = 0; //Move(speed * vector * aircaft.MoveLRSpeed * Time.deltaTime);*/ Balance(Quaternion.Euler(body.eulerAngles.x, body.eulerAngles.y, -aircaft.AxisFB * speed), aircaft.RoteLRSpeed * Time.deltaTime * 3); //print("MoveLR" + speed); } public override void Operational() { //操作 // Altigraph(); CurrentSpeed = Mathf.Lerp(CurrentSpeed, 0, Time.deltaTime/3); //if (!IsUD) { currentUDSpeed = Mathf.Lerp(currentUDSpeed, 0, Time.deltaTime); //} if (IsOnGround && currentUDSpeed<0) { currentUDSpeed = 0; } currentMLRSpeed = Mathf.Lerp(currentMLRSpeed, 0, Time.deltaTime); currentRLRSpeed = Mathf.Lerp(currentRLRSpeed, 0, Time.deltaTime/2); Move(Vector3.Cross(Vector3.up, body.right) * -CurrentSpeed * Time.deltaTime); Move(Vector3.up * currentUDSpeed * Time.deltaTime); Move(-currentMLRSpeed * Vector3.Cross(body.forward,Vector3.up) * Time.deltaTime); Rote(currentRLRSpeed * Vector3.up * Time.deltaTime); Balance(); } public override void RoteLR(float speed) { //左右旋轉 if ((IsSing) || IsOnGround) return; currentRLRSpeed += speed * aircaft.Acc * Time.deltaTime; currentRLRSpeed = Mathf.Clamp(currentRLRSpeed, -aircaft.RoteLRSpeed, aircaft.RoteLRSpeed); IsLRB = false; //Rote(speed * Vector3.up * aircaft.RoteLRSpeed * Time.deltaTime ); Balance(Quaternion.Euler(body.eulerAngles.x, body.eulerAngles.y, -aircaft.AxisLR * speed), aircaft.RoteLRSpeed * Time.deltaTime/5); } public override void RoteUD(float speed) { //上下旋轉 //速度和角度 /*if ((IsSing) || IsOnGround ) return; IsFBB = false; Balance(Quaternion.Euler(aircaft.AxisFB * speed, body.eulerAngles.y, body.eulerAngles.z), aircaft.RoteFBSpeed * Time.deltaTime * CurrentSpeed / aircaft.MoveFBSpeed);*/ //這個功能是實現直升機的升降 currentUDSpeed += speed * Time.deltaTime * aircaft.Acc; currentUDSpeed = Mathf.Clamp(currentUDSpeed, -5, 5); //print("RoteUD" + speed); } public override void Balance() { if (IsSing) return; if (IsLRB) { Balance(Quaternion.Euler(body.eulerAngles.x, body.eulerAngles.y, 0), aircaft.RoteLRSpeed * Time.deltaTime / 2.2f); } if (IsFBB) { Balance(Quaternion.Euler(0, body.eulerAngles.y, body.eulerAngles.z), aircaft.RoteFBSpeed * Time.deltaTime / 2.3f); } IsLRB = true; IsFBB = true; } private float lastSTime; public override void StuntLR(float axis) { if ((IsSing) || IsOnGround && CurrentSpeed < aircaft.MoveFBSpeed / 3.6f) return; if (!IsSing) { IsSing = true; StartCoroutine(SLR(axis)); } } IEnumerator SLR(float speed) { //這個特技是指側飛,獲取按下飛機的坐標和速度F1,計算出側飛半徑, //直到飛行角度和F1垂直的位置 speed = (speed > 0 ? 1 : -1); Vector3 aim = body.right * (speed); aim.y = 0; while (Vector3.Dot(aim.normalized, body.forward.normalized) < 0.99f) { Rote(speed * Vector3.up * aircaft.RoteLRSpeed * Time.deltaTime); Balance(Quaternion.Euler(body.eulerAngles.x, body.eulerAngles.y, -85 * (speed)), aircaft.RoteLRSpeed * Time.deltaTime * 3.8f); Balance(Quaternion.Euler(0, body.eulerAngles.y, body.eulerAngles.z), aircaft.RoteFBSpeed * Time.deltaTime * 1.8f); yield return new WaitForFixedUpdate(); } while ((body.eulerAngles.z > 15) && (body.eulerAngles.z < 180) || (body.eulerAngles.z < 345) && (body.eulerAngles.z > 270)) { Balance(Quaternion.Euler(0, body.eulerAngles.y, body.eulerAngles.z), aircaft.RoteFBSpeed * Time.deltaTime); Balance(Quaternion.Euler(body.eulerAngles.x, body.eulerAngles.y, 0), aircaft.RoteLRSpeed * Time.deltaTime * 3); yield return new WaitForFixedUpdate(); } IsSing = false; } public override void StuntUD(float axis) { if ((IsSing) || IsOnGround && CurrentSpeed < aircaft.MoveFBSpeed / 3.6f) return; if (!IsSing) { IsSing = true; StartCoroutine(SUD(axis)); } } IEnumerator SUD(float speed) { //這個特技是指側飛,獲取按下飛機的坐標和速度F1,計算出側飛半徑, //直到飛行角度和F1垂直的位置 speed = (speed > 0 ? 1 : -1); Vector3 aim = -body.forward; aim.y = 0; while (Vector3.Dot(aim.normalized, body.forward.normalized) < 0.8f) { Vector3 v = body.right; v.y = 0; Rote(body.right * Time.deltaTime * -90 * speed); Move(-Vector3.up * speed * Time.deltaTime * 10 * (CurrentSpeed / (aircaft.OffSpeed))); //body.Rotate(Vector3.right * Time.deltaTime * -90,Space.Self); //Balance(Quaternion.Euler(body.eulerAngles.x, body.eulerAngles.y, 0), aircaft.RoteLRSpeed * Time.deltaTime*5); yield return new WaitForFixedUpdate(); } while ((body.eulerAngles.z > 15) && (body.eulerAngles.z < 180) || (body.eulerAngles.z < 345) && (body.eulerAngles.z > 270)) { Balance(Quaternion.Euler(0, body.eulerAngles.y, body.eulerAngles.z), aircaft.RoteFBSpeed * Time.deltaTime); Balance(Quaternion.Euler(body.eulerAngles.x, body.eulerAngles.y, 0), aircaft.RoteLRSpeed * Time.deltaTime * 3); yield return new WaitForFixedUpdate(); } IsSing = false; } }
關於測試代碼也很簡單,輸入檢測一下,然后調用直升機的控制代碼就行了,這里就不提供了。
