当前位置: 首页 > news >正文

【unity实战】简易的车辆控制系统

最终效果

在这里插入图片描述

文章目录

  • 最终效果
  • 前言
  • 一、实战
    • 1、模型下载
    • 2、添加刚体和碰撞体
    • 3、提前车辆,并添加WheelCollider组件,配置参数
    • 4、车辆移动
    • 5、刹车
    • 6、转向和车辆重心
    • 7、动画化车轮
    • 8、相机跟随
  • 二、最终车辆控制代码
  • 三、车辆引擎声音
  • 专栏推荐
  • 完结

前言

在游戏开发中,车辆控制系统是一个非常常见且重要的功能模块。无论是赛车游戏、开放世界游戏还是模拟驾驶游戏,一个稳定且真实的车辆控制系统都能大大提升玩家的游戏体验。

本教程将带领大家从零开始,在Unity中实现一个简易但功能完整的车辆控制系统。

这个系统采用了Unity内置的WheelCollider组件来处理车辆物理,相比完全自定义的物理实现更加稳定高效。我们还会学习如何调整车辆的重心、转向灵敏度等参数,使车辆操控感更加真实。

最终我们将得到一个可以自由驾驶的车辆,具备加速、刹车、转向等基本功能,并且车轮会随着运动正确旋转,相机也会智能跟随车辆移动。

让我们开始这个有趣的项目吧!在实现过程中,你可以随时调整参数来获得不同的驾驶体验,找到最适合你游戏的操控感觉。

一、实战

1、模型下载

https://assetstore.unity.com/packages/3d/vehicles/land/1950s-classic-car-6-variant-322054
在这里插入图片描述

2、添加刚体和碰撞体

在这里插入图片描述

3、提前车辆,并添加WheelCollider组件,配置参数

在这里插入图片描述

4、车辆移动

// 车轴枚举
public enum Axel
{Front,  // 前轮Rear    // 后轮
}// 车轮结构体
[Serializable]
public struct Wheel
{public GameObject wheelModel;        // 车轮模型public WheelCollider wheelCollider; // 车轮碰撞器public Axel axel;                    // 所属车轴
}[SerializeField] public float maxAcceleration = 10.0f;    // 最大加速度
public List<Wheel> wheels;               // 车轮列表float _moveInput;     // 移动输入值private Rigidbody _carRb;     // 车辆刚体组件void Start()
{// 获取刚体组件并设置重心_carRb = GetComponent<Rigidbody>();
}void Update()
{GetInputs();        // 获取输入
}void FixedUpdate()
{Move();     // 移动控制
}// 获取输入
void GetInputs()
{_moveInput = Input.GetAxis("Vertical");   // 获取垂直输入
}// 移动控制
void Move()
{foreach (var wheel in wheels){// 设置车轮马达扭矩wheel.wheelCollider.motorTorque = _moveInput * 600 * maxAcceleration;}
}

配置
在这里插入图片描述

效果
在这里插入图片描述

5、刹车

public float brakeAcceleration = 50.0f;  // 刹车加速度void FixedUpdate()
{Move();     // 移动控制Brake();    // 刹车控制
}// 刹车控制
void Brake()
{// 如果按下空格键或没有移动输入if (Input.GetKey(KeyCode.Space) || _moveInput == 0){foreach (var wheel in wheels){// 设置刹车扭矩wheel.wheelCollider.brakeTorque = 300 * brakeAcceleration;}}else{foreach (var wheel in wheels){// 取消刹车扭矩wheel.wheelCollider.brakeTorque = 0;}}
}

效果
在这里插入图片描述

6、转向和车辆重心

public float turnSensitivity = 1.0f;    // 转向灵敏度
public float maxSteerAngle = 30.0f;      // 最大转向角度
public Vector3 centerOfMass;            // 车辆重心
float _steerInput;    // 转向输入值void Start()
{// 获取刚体组件并设置重心_carRb = GetComponent<Rigidbody>();_carRb.centerOfMass = centerOfMass;
}void FixedUpdate()
{Move();     // 移动控制Brake();    // 刹车控制Steer();    // 转向控制
}// 获取输入
void GetInputs()
{_moveInput = Input.GetAxis("Vertical");   // 获取垂直输入_steerInput = Input.GetAxis("Horizontal"); // 获取水平输入
}// 转向控制
void Steer()
{foreach (var wheel in wheels){// 只对前轮进行转向if (wheel.axel == Axel.Front){var _steerAngle = _steerInput * turnSensitivity * maxSteerAngle;// 平滑过渡转向角度wheel.wheelCollider.steerAngle = Mathf.Lerp(wheel.wheelCollider.steerAngle, _steerAngle, 0.6f);}}
}

效果
在这里插入图片描述

7、动画化车轮

void Update()
{GetInputs();        // 获取输入AnimateWheels();     // 动画化车轮
}// 动画化车轮
void AnimateWheels()
{foreach (var wheel in wheels){Quaternion rot;Vector3 pos;// 获取车轮碰撞器的世界位置和旋转wheel.wheelCollider.GetWorldPose(out pos, out rot);// 更新车轮模型的位置和旋转wheel.wheelModel.transform.position = pos;wheel.wheelModel.transform.rotation = rot;}
}

效果
在这里插入图片描述

8、相机跟随

参考:【unity知识】最新的Cinemachine3简单使用介绍

在这里插入图片描述
效果
在这里插入图片描述

二、最终车辆控制代码

using UnityEngine;
using System;
using System.Collections.Generic;public class CarController : MonoBehaviour
{// 车轴枚举public enum Axel{Front,  // 前轮Rear    // 后轮}// 车轮结构体[Serializable]public struct Wheel{public GameObject wheelModel;        // 车轮模型public WheelCollider wheelCollider; // 车轮碰撞器public Axel axel;                    // 所属车轴}[SerializeField] public float maxAcceleration = 10.0f;    // 最大加速度public float brakeAcceleration = 50.0f;  // 刹车加速度public float turnSensitivity = 1.0f;    // 转向灵敏度public float maxSteerAngle = 30.0f;      // 最大转向角度public Vector3 centerOfMass;            // 车辆重心public List<Wheel> wheels;               // 车轮列表float _moveInput;     // 移动输入值float _steerInput;    // 转向输入值private Rigidbody _carRb;     // 车辆刚体组件void Start(){// 获取刚体组件并设置重心_carRb = GetComponent<Rigidbody>();_carRb.centerOfMass = centerOfMass;}void Update(){GetInputs();        // 获取输入AnimateWheels();     // 动画化车轮}void FixedUpdate(){Move();     // 移动控制Brake();    // 刹车控制Steer();    // 转向控制}// 获取输入void GetInputs(){_moveInput = Input.GetAxis("Vertical");   // 获取垂直输入_steerInput = Input.GetAxis("Horizontal"); // 获取水平输入}// 移动控制void Move(){foreach (var wheel in wheels){// 设置车轮马达扭矩wheel.wheelCollider.motorTorque = _moveInput * 600 * maxAcceleration;}}// 转向控制void Steer(){foreach (var wheel in wheels){// 只对前轮进行转向if (wheel.axel == Axel.Front){var _steerAngle = _steerInput * turnSensitivity * maxSteerAngle;// 平滑过渡转向角度wheel.wheelCollider.steerAngle = Mathf.Lerp(wheel.wheelCollider.steerAngle, _steerAngle, 0.6f);}}}// 刹车控制void Brake(){// 如果按下空格键或没有移动输入if (Input.GetKey(KeyCode.Space) || _moveInput == 0){foreach (var wheel in wheels){// 设置刹车扭矩wheel.wheelCollider.brakeTorque = 300 * brakeAcceleration;}}else{foreach (var wheel in wheels){// 取消刹车扭矩wheel.wheelCollider.brakeTorque = 0;}}}// 动画化车轮void AnimateWheels(){foreach (var wheel in wheels){Quaternion rot;Vector3 pos;// 获取车轮碰撞器的世界位置和旋转wheel.wheelCollider.GetWorldPose(out pos, out rot);// 更新车轮模型的位置和旋转wheel.wheelModel.transform.position = pos;wheel.wheelModel.transform.rotation = rot;}}
}

三、车辆引擎声音

新增脚本,根据速度计算的动态音高

using UnityEngine;public class CarSounds : MonoBehaviour
{[Header("速度参数")]public float maxSpeed = 40f;       // 引擎声音最大速度阈值private float currentSpeed;  // 当前车辆速度[Header("音频参数")]public float minPitch = 0.2f;    // 引擎最小音高 (默认值示例)public float maxPitch = 1f;    // 引擎最大音高 (默认值示例)private float pitchFromCar;      // 根据速度计算的动态音高private Rigidbody carRb;     // 车辆刚体组件private AudioSource carAudio; // 音频源组件void Start(){// 获取组件引用carAudio = GetComponent<AudioSource>();carRb = GetComponent<Rigidbody>();}void Update(){EngineSound(); // 每帧更新引擎声音}/// <summary>/// 根据车速动态调整引擎音效/// </summary>void EngineSound(){// 获取当前速度(忽略垂直方向)currentSpeed = carRb.linearVelocity.magnitude;// 计算速度比例映射到音高范围pitchFromCar = Mathf.Clamp(currentSpeed / maxSpeed, minPitch, maxPitch);carAudio.pitch =  pitchFromCar;}
}

专栏推荐

地址
【unity游戏开发入门到精通——C#篇】
【unity游戏开发入门到精通——unity通用篇】
【unity游戏开发入门到精通——unity3D篇】
【unity游戏开发入门到精通——unity2D篇】
【unity实战】
【制作100个Unity游戏】
【推荐100个unity插件】
【实现100个unity特效】
【unity框架/工具集开发】
【unity游戏开发——模型篇】
【unity游戏开发——InputSystem】
【unity游戏开发——Animator动画】
【unity游戏开发——UGUI】
【unity游戏开发——联网篇】
【unity游戏开发——优化篇】
【unity游戏开发——shader篇】
【unity游戏开发——编辑器扩展】
【unity游戏开发——热更新】
【unity游戏开发——网络】

完结

好了,我是向宇,博客地址:https://xiangyu.blog.csdn.net,如果学习过程中遇到任何问题,也欢迎你评论私信找我。

赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章中存在错误或者有更好的解决方法,也欢迎评论私信告诉我哦!
在这里插入图片描述

http://www.dtcms.com/a/310799.html

相关文章:

  • 从零开始:Kaggle 竞赛实战入门指南
  • 鸿蒙系统PC安装指南
  • 【RH124 问答题】第 9 章 控制服务和守护进程
  • 测试分类:详解各类测试方式与方法
  • 告别“AI味”图像!最新开源AI模型FLUX.1-Krea实现真实光影生成
  • 【n8n】如何跟着AI学习n8n【05】:Merge节点和子流程调用
  • Prim算法
  • 交叉编译简介
  • 【JAVA面试】基础篇
  • 广东省省考备考(第六十三天8.1)——资料分析、数量(强化训练)
  • 【AI应用】 能源保供战:AI大模型如何守护万家灯火?
  • Day37| 完全背包、518.零钱兑换II、377. 组合总和 Ⅳ、70. 爬楼梯 (进阶)
  • 流式编程学习思路
  • 疯狂星期四文案网第26天运营日记
  • 【PyTorch✨】01 初识PyTorch
  • 潜伏式 AGV 与叉车 AGV 充电桩的技术差异及应用分析
  • 在国内注册谷歌邮箱(资源是免费下载的)
  • 第13届蓝桥杯Python青少组中/高级组选拔赛(STEMA)2021年11月27日真题
  • Linux文件系统:从内核到缓冲区的奥秘
  • PyTorch深度学习入门记录8
  • 逻辑回归参数调优实战指南
  • MeshDepthMaterial
  • AI论文工具的应用与发展(2025年总结)
  • SQL数据库连接Python实战:疫情数据指挥中心搭建指南
  • 嵌入式学习之硬件——51单片机 1.0
  • QPS 与 TPS 的详细解释及核心区别
  • DLL错误专修工具_TBI3264.exe下载安装教程(一键修复DLL缺失/错误)​
  • 初识微服务
  • Trust Management System (TMS)
  • 把上次做的图片的API改成国内版,让图片返回速度提升一个档次