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

2024-02-10 17:10

本文主要是介绍Unity飞机控制器制作(普通飞机和直升机),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这个飞机控制器是跟着油管作者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<Rigidbody>();}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<Rigidbody>();audioSource = GetComponent<AudioSource>();}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.飞机底部有武器,炸弹之类的,可以尝试添加代码让飞机发射武器并且添加爆炸的粒子特效。

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

 

 

这篇关于Unity飞机控制器制作(普通飞机和直升机)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/697637

相关文章

什么是 Ubuntu LTS?Ubuntu LTS和普通版本区别对比

《什么是UbuntuLTS?UbuntuLTS和普通版本区别对比》UbuntuLTS是Ubuntu操作系统的一个特殊版本,旨在提供更长时间的支持和稳定性,与常规的Ubuntu版本相比,LTS版... 如果你正打算安装 Ubuntu 系统,可能会被「LTS 版本」和「普通版本」给搞得一头雾水吧?尤其是对于刚入

使用Python制作一个PDF批量加密工具

《使用Python制作一个PDF批量加密工具》PDF批量加密‌是一种保护PDF文件安全性的方法,通过为多个PDF文件设置相同的密码,防止未经授权的用户访问这些文件,下面我们来看看如何使用Python制... 目录1.简介2.运行效果3.相关源码1.简介一个python写的PDF批量加密工具。PDF批量加密

用Unity2D制作一个人物,实现移动、跳起、人物静止和动起来时的动画:中(人物移动、跳起、静止动作)

上回我们学到创建一个地形和一个人物,今天我们实现一下人物实现移动和跳起,依次点击,我们准备创建一个C#文件 创建好我们点击进去,就会跳转到我们的Vision Studio,然后输入这些代码 using UnityEngine;public class Move : MonoBehaviour // 定义一个名为Move的类,继承自MonoBehaviour{private Rigidbo

OpenStack离线Train版安装系列—0制作yum源

本系列文章包含从OpenStack离线源制作到完成OpenStack安装的全部过程。 在本系列教程中使用的OpenStack的安装版本为第20个版本Train(简称T版本),2020年5月13日,OpenStack社区发布了第21个版本Ussuri(简称U版本)。 OpenStack部署系列文章 OpenStack Victoria版 安装部署系列教程 OpenStack Ussuri版

OpenStack镜像制作系列5—Linux镜像

本系列文章主要对如何制作OpenStack镜像的过程进行描述记录 CSDN:OpenStack镜像制作教程指导(全) OpenStack镜像制作系列1—环境准备 OpenStack镜像制作系列2—Windows7镜像 OpenStack镜像制作系列3—Windows10镜像 OpenStack镜像制作系列4—Windows Server2019镜像 OpenStack镜像制作

OpenStack镜像制作系列4—Windows Server2019镜像

本系列文章主要对如何制作OpenStack镜像的过程进行描述记录  CSDN:OpenStack镜像制作教程指导(全) OpenStack镜像制作系列1—环境准备 OpenStack镜像制作系列2—Windows7镜像 OpenStack镜像制作系列3—Windows10镜像 OpenStack镜像制作系列4—Windows Server2019镜像 OpenStack镜像制作系

OpenStack镜像制作系列2—Windows7镜像

本系列文章主要对如何制作OpenStack镜像的过程进行描述记录 CSDN:OpenStack镜像制作教程指导(全) OpenStack镜像制作系列1—环境准备 OpenStack镜像制作系列2—Windows7镜像 OpenStack镜像制作系列3—Windows10镜像 OpenStack镜像制作系列4—Windows Server2019镜像 OpenStack镜像制作系列

OpenStack镜像制作系列1—环境准备

本系列文章主要对如何制作OpenStack镜像的过程进行描述记录 CSDN:OpenStack镜像制作教程指导(全) OpenStack镜像制作系列1—环境准备 OpenStack镜像制作系列2—Windows7镜像 OpenStack镜像制作系列3—Windows10镜像 OpenStack镜像制作系列4—Windows Server2019镜像 OpenStack镜像制作

CSDN:OpenStack镜像制作教程指导(全)

本系列文章主要对如何制作OpenStack镜像的过程进行描述记录,涉及基本环境准备、常见类型操作系统的镜像制作。 让你可以从零开始安装一个操作系统,并支持个性化制作OpenStack镜像。 CSDN:OpenStack镜像制作教程指导(全) OpenStack镜像制作系列1—环境准备 OpenStack镜像制作系列2—Windows7镜像 OpenStack镜像制作系列3—Windows

docker学习系列(四)制作基础的base项目镜像--jdk+tomcat

前面已经完成了docker的安装以及使用,现在我们要将自己的javaweb项目与docker结合 1.1准备jdk+tomcat软件 ​​我下载了apache-tomcat-7.0.68.tar.gz和jdk-7u79-linux-x64.tar.gz,存储于Linux机器的本地目录/usr/ect/wt/下(利用xshell上传)。利用linux命令 tar -zxvf apache-tom