基于unity的直升机模拟设计
上一篇文章介绍了使用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; } }
关于测试代码也很简单,输入检测一下,然后调用直升机的控制代码就行了,这里就不提供了。