您的位置:首页 > 移动开发 > Unity3D

基于unity的直升机模拟设计

2015-08-08 18:00 666 查看
上一篇文章介绍了使用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;
}
}


关于测试代码也很简单,输入检测一下,然后调用直升机的控制代码就行了,这里就不提供了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: