Unity飞机控制器制作(普通飞机和直升机)

您所在的位置:网站首页 飞机模型简单制作方法 Unity飞机控制器制作(普通飞机和直升机)

Unity飞机控制器制作(普通飞机和直升机)

2024-07-13 00:17:50| 来源: 网络整理| 查看: 265

这个飞机控制器是跟着油管作者b3agz的视频做的,大家有时间可以看原视频(作者的声音很有磁性,听起来比较舒服)

普通飞机视频:Simple Physics Based Plane Controller in Unity - YouTube

直升机视频: Simple Physics Based Helicopter Controller in Unity - YouTube

飞机的飞行状态解释:  

这张图是从视频中截的,对比Unity中的飞机坐标轴来看

 

所以Roll Axis对应的是Z轴,Yaw Axis对应的是Y轴,Pitch Axis对应的是X轴,所以飞机绕Roll Axis的旋转就是绕Z轴的旋转,其余的同理。飞机主要的状态就是绕着这些轴去旋转,所以教程中制作的飞机也可以绕这些轴旋转做出旋转的动作,你可以想象一下绕不同轴旋转的样子。

准备

首先导入模型,我这里使用的模型是一架小飞机,是商店里的免费资源,地址在这 

Rusty plane | 3D 飞机 | Unity Asset Store

首先导入飞机模型,然后创建一个空物体MyPlane,把飞机模型作为MyPlane的子物体,调整好飞机的朝向,使得飞机的面朝方向为Z轴,和上面的图片一样(就是把子物体Y轴旋转角度设为-90)。然后添加Rigidbody组件和BoxCollider组件设置好大小,先不要勾选刚体组件的Use Gravity选项,暂时不启用重力。设置的值如下图:

此外还需要做一件事,就是打开Edit下拉选项中的Project Setting,在Input Manager选项中可以看到两个Horizontal,把下面的一个改成如下内容:

 起始你也开始更Horizontal为Roll,把Vertical改为Pitch,起始也可以不改。

最后记得创建一块地板!

脚本编写 绕轴旋转

先不考虑重力,先实现飞机绕各个轴旋转的状态

using System.Collections; using System.Collections.Generic; using UnityEngine; public class BiplaneController : MonoBehaviour { //飞机的旋转灵敏参数 public float responsiveness = 10f; //定义三个轴 //左右摆动 private float roll; //爬升或者俯冲 private float pitch; //左右转动 private float yaw; private Rigidbody rb; //根据飞机质量来调节飞机旋转的灵敏度 private float responseModifier { get { return (rb.mass / 10f) * responsiveness; } } private void Awake { rb = GetComponent(); } private void HandleInputs() { roll = Input.GetAxis("Horizontial"); pitch = Input.GetAxis("Vertical"); yaw = nput.GetAxis("Yaw"); } private void Update() { HandleInputs(); } private void FixedUpdate() { //施加扭矩 rb.AddTorque(transform.up * yaw * responseModifier); rb.AddTorque(transform.right * pitch* responseModifier); rb.AddTorque(-transform.forward * roll * responseModifier); } }

此时将飞机放在空中,然后按下W飞机会俯冲,S会爬升,A向左滚筒旋转,D向右滚筒旋转,Q向左转向,E向右转向。

简单解释这段代码,原理就是为飞机在不同的轴上施加扭矩也就是通过AddTorque来实现旋转的效果,你可以联系和实现物体前后左右行走的代码来理解。此外如果你觉得飞机转的太快了,那么你可以调节responsiveness这个值的大小,这个值越大转得越灵敏,也就越难操纵。

升力

这个时候将MyPlane的刚体组件的Use Gravity勾选选上,那么飞机会掉在地上。按啥都没用了。这时候就要为飞机提供升力了。现实中的普通飞机一般都是通过先在地面上加速,然后达到一定速度后才可以起飞的(直升机在下面实现),提供升力的脚本原理也是这样的,我们延续这上面的代码接着写:

using System.Collections; using System.Collections.Generic; using UnityEngine; using TMPro; public class BiplaneController : MonoBehaviour { //油门百分比值 public float throttle; //油门增量,就是指每次加油门油门百分比的增加值 public float throttleIncrement = 0.1f; //油门最大时可以提供的冲量 public float maxThrust = 200f; //飞机的升力 public float lift = 135f; //.... private void HandleInputs() { //... //按下空格键加油门百分比 if(Input.GetKey(KeyCode.Space)) throttle += throttleIncrement; //按下左Ctrl减油门百分比 else if(Input.GetKey(KeyCode.LeftCtrl)) throttle -= throttleIncrement; //限制油门百分比大小 throttle = Mathf.Clamp(throttle,0,100f); } private void FixUpdate() { //施加前进力 rb.AddForce(transform.forward * Thrust * throttle); //根据飞机速度施加升力 rb.AddForce(rb.transform.up * rb.velocity.magnitude * lift); //.... } }

代码很简单,当你按下空格键时,油门百分比值会逐步增加,将这个百分比值乘以油门最大时提供的冲量(不知道叫什么好,这里就叫冲量), 将这个值首先用来给飞机加速,也就是给飞机朝向的方向施加力,然后由该力得到飞机刚体的速度,然后再施加升力来客服飞机的重力从而让飞机飞起来。

杂项 

首先让飞机的螺旋桨转起来,根据油门量的大小来让它转起来,越大转的越快。在加个声音,油门越大声音越大,加声音请在MyPlane下添加AudioSource组件,然后把组件中的Loop勾选上,不然就放了一次音频就不响了。

using System.Collections; using System.Collections.Generic; using UnityEngine; public class BiplaneController : MonoBehaviour { //.... [SerializeField] Transform propella; [SerializeField] private AudioSource audioSource; private void Update() { //.... propella.Rotate(Vector3.right * throttle); audioSource.volume = _throttle * 0.01f; } //.... }

然后在添加一个摄像头跟随脚本CameraController 

using System.Collections; using System.Collections.Generic; using UnityEngine; public class CameraController : MonoBehaviour { [SerializeField] Transform[] povs; [SerializeField] float Speed; private int index = 0; private Vector3 target; private void Update() { if (Input.GetKeyDown(KeyCode.Alpha1)) index = 0; else if (Input.GetKeyDown(KeyCode.Alpha2)) index = 1; else if (Input.GetKeyDown(KeyCode.Alpha3)) index = 2; else if (Input.GetKeyDown(KeyCode.Alpha4)) index = 3; target = povs[index].position; } private void FixedUPdate() { transform.position = Vector3.MoveTowards(transfoem.position,target,Time.deltaTime * Speed); transform.forward = povs[index].forward; } }

这个脚本的主要作用就是当我们按下1,2,3,4后切换视角,就和地平线4在开车时换视角一样。将该脚本挂载到Main Camera上,然后在MyPlane下创建几个空物体,选择合适的角度和位置,我这里是四个位置,然后把这四个位置拖到脚本的povs上,Speed设为合适的值。这样整个飞机就完成了。

直升机控制器

直升机控制器和普通的飞机差不多,有一个地方有差别就是直升机不需要在地面上加速,直接就可以飞起来了。代码如下:

using System.Collections; using System.Collections.Generic; using UnityEngine; public class HelicopterController : MonoBehaviour { private Rigidbody rb; [SerializeField] private float _responsiveness = 500f; [SerializeField] private float _throttleAmt = 25f; private float _throttle; private float _roll; private float _pitch; private float _yaw; [SerializeField] private float _rotorSpeedModifier = 10f; [SerializeField] private Transform _rotorsTransform; [SerializeField] private Transform _rotorsTransform1; [SerializeField] private AudioSource audioSource; private void Awake() { rb = GetComponent(); audioSource = GetComponent(); } public float turnSpeed = 5f; private void Update() { HandInputs(); _rotorsTransform.Rotate(Vector3.up * _throttle * _rotorSpeedModifier); _rotorsTransform1.Rotate(Vector3.right * _throttle * 1f,Space.Self); audioSource.volume = _throttle * 0.01f; } private void FixedUpdate() { rb.AddForce(transform.up * _throttle, ForceMode.Impulse); rb.AddTorque(transform.up * _yaw * _responsiveness); rb.AddTorque(-transform.forward * _roll * _responsiveness * 0.5f); rb.AddTorque(transform.right * _pitch * _responsiveness); } private void HandInputs() { _roll = Input.GetAxis("Horizontal"); _pitch = Input.GetAxis("Vertical"); _yaw = Input.GetAxis("Yaw"); if (Input.GetKey(KeyCode.Space)) _throttle += Time.deltaTime * _throttleAmt; else if (Input.GetKey(KeyCode.LeftControl)) _throttle -= Time.deltaTime * _throttleAmt; _throttle = Mathf.Clamp(_throttle, 0, 100f); } }

简单解释下和普通飞机的区别。

首先是油门这里没有采用百分比的方式了,而是直接加,每次加25N(单位是牛,也许吧,不重要)。然后再FixedUpdate函数中,只施加了一个力,具体是rb.AddForce(transform.up * _throttle, ForceMode.Impulse); 后面的ForceMode类型是Impulse,也就是直接施加力。最后定义了两个螺旋桨,一个是直升机顶部的螺旋桨,一个是尾部的螺旋桨,都是按照油门百分比加的,起始尾部应该不是,但是这里不在深究了。

最后注意下,旋转可能会出问题,就是旋转时螺旋桨错位了,出现很诡异的现象,就像下面这样:

螺旋桨旋转飞了,这是因为螺旋桨的轴心和中心不在一个位置,所以螺旋桨会绕着轴心旋转,解决的办法看这篇文章

Unity重置模型物体的轴心为中心_模型的 轴心_星·雨的博客-CSDN博客

改进建议

1.都是飞机的控制器脚本并且有很大部分一样,所以可以重构着两段代码,把一样的部分写在一起。

2.飞机螺旋桨旋转得很僵硬,可以平滑旋转。

3.飞机底部有武器,炸弹之类的,可以尝试添加代码让飞机发射武器并且添加爆炸的粒子特效。

最后欢迎各位提出问题,理性讨论。 

   


【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭