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

【Unity3D赛车游戏】【四】在Unity中添加阿克曼转向,下压力,质心会让汽车更稳定

在这里插入图片描述


👨‍💻个人主页:@元宇宙-秩沅

👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅!

👨‍💻 本文由 秩沅 原创

👨‍💻 收录于专栏:Unity游戏demo

🅰️Unity3D赛车游戏



文章目录

    • 🅰️Unity3D赛车游戏
    • 前言
    • 🎶(==A==)车辆优化——阿克曼转向添加
        • 😶‍🌫️认识阿克曼转向
        • 😶‍🌫️区别:
        • 😶‍🌫️关键代码
        • 😶‍🌫️完整代码
    • 🎶(==B==)车辆优化——车身持续稳定的优化
        • 😶‍🌫️速度属性实时转换
        • 😶‍🌫️为车子添加下压力
        • 😶‍🌫️质心的添加centerMess
        • 😶‍🌫️轮胎的平滑度的显示
    • 🅰️


前言


😶‍🌫️版本: Unity2021
😶‍🌫️适合人群:Unity初学者
😶‍🌫️学习目标:3D赛车游戏的基础制作
😶‍🌫️技能掌握:



🎶(A车辆优化——阿克曼转向添加


😶‍🌫️认识阿克曼转向

引用:阿克曼转向是一种现代汽车的转向方式,也是移动机器人的一种运动模式,在汽车转弯的时候,内外轮转过的角度不一样,内侧轮胎转弯半径小于外侧轮胎

原理图:
_____________在这里插入图片描述
简单理解一个杆子把左轮和右轮连接起来一起转。

在这里插入图片描述
左轮的旋转的半径小于右轮

优点:大大减小了车轮转向需要的空间,转向更加稳定

  • 阿克曼公式:

在这里插入图片描述
β为汽车前外轮转角,α为汽车前内轮转角,K为两主销中心距,L为轴距。

在这里插入图片描述

😶‍🌫️区别:

  • 未添加阿克曼转向之前的原理:

    通过控制轮子的最大转向范围来转向

在这里插入图片描述

  • 添加之后

    更稳定,机动性更强

在这里插入图片描述

😶‍🌫️关键代码

  • 后轮距尺寸设置为1.5f ,轴距设置为2.55f ,radius 默认为6,radius 越大旋转的角度看起来越小
 if (horizontal > 0 ) {
//后轮距尺寸设置为1.5f ,轴距设置为2.55f ,radius 默认为6,radius 越大旋转的角度看起来越小wheels[0].steerAngle = Mathf.Rad2Deg * Mathf.Atan(2.55f / (radius + (1.5f / 2))) * horizontal;wheels[1].steerAngle = Mathf.Rad2Deg * Mathf.Atan(2.55f / (radius - (1.5f / 2))) * horizontal;} else if (horizontal < 0 ) {                                                          wheels[0].steerAngle = Mathf.Rad2Deg * Mathf.Atan(2.55f / (radius - (1.5f / 2))) * horizontal;wheels[1].steerAngle = Mathf.Rad2Deg * Mathf.Atan(2.55f / (radius + (1.5f / 2))) * horizontal;} else {wheels[0].steerAngle =0;wheels[1].steerAngle =0;}

😶‍🌫️完整代码

在这里插入图片描述

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//-------------------------------------
//—————————————————————————————————————
//___________项目:       ______________
//___________功能:  车轮的运动
//___________创建者:_______秩沅________
//_____________________________________
//-------------------------------------//驱动模式的选择
public enum EDriveType
{frontDrive,   //前轮驱动backDrive,    //后轮驱动allDrive      //四驱
}public class WheelMove : MonoBehaviour
{//-------------------------------------------//四个轮子的碰撞器public WheelCollider[] wheels ;//网格的获取public GameObject[] wheelMesh;//扭矩力度public float motorflaot = 200f;//初始化三维向量和四元数private Vector3 wheelPosition = Vector3.zero;private Quaternion wheelRotation = Quaternion.identity;//-------------------------------------------//驱动模式选择 _默认前驱public EDriveType DriveType = EDriveType.frontDrive;//轮半径public float radius = 0.25f;private void FixedUpdate(){WheelsAnimation(); //车轮动画VerticalContorl(); //驱动管理HorizontalContolr(); //转向管理}//垂直轴方向管理(驱动管理)public void VerticalContorl(){switch (DriveType){case EDriveType.frontDrive: //选择前驱if (InputManager.InputManagerment.vertical != 0) //当按下WS键时生效{for (int i = 0; i < wheels.Length - 2; i++){//扭矩力度wheels[i].motorTorque = InputManager.InputManagerment.vertical *(motorflaot / 2); //扭矩马力归半}}break;case EDriveType.backDrive://选择后驱if (InputManager.InputManagerment.vertical != 0) //当按下WS键时生效{for (int i = 2; i < wheels.Length; i++){//扭矩力度wheels[i].motorTorque = InputManager.InputManagerment.vertical * (motorflaot / 2); //扭矩马力归半}}break;case EDriveType.allDrive://选择四驱if (InputManager.InputManagerment.vertical != 0) //当按下WS键时生效{for (int i = 0; i < wheels.Length; i++){//扭矩力度wheels[i].motorTorque = InputManager.InputManagerment.vertical * ( motorflaot / 4 ); //扭矩马力/4}}break;default:break;}}//水平轴方向管理(转向管理)public void HorizontalContolr(){if (InputManager.InputManagerment.horizontal > 0){//后轮距尺寸设置为1.5f ,轴距设置为2.55f ,radius 默认为6,radius 越大旋转的角度看起来越小wheels[0].steerAngle = Mathf.Rad2Deg * Mathf.Atan(2.55f / (radius + (1.5f / 2))) * InputManager.InputManagerment.horizontal;wheels[1].steerAngle = Mathf.Rad2Deg * Mathf.Atan(2.55f / (radius - (1.5f / 2))) * InputManager.InputManagerment.horizontal;}else if (InputManager.InputManagerment.horizontal < 0){wheels[0].steerAngle = Mathf.Rad2Deg * Mathf.Atan(2.55f / (radius - (1.5f / 2))) * InputManager.InputManagerment.horizontal;wheels[1].steerAngle = Mathf.Rad2Deg * Mathf.Atan(2.55f / (radius + (1.5f / 2))) * InputManager.InputManagerment.horizontal;}else{wheels[0].steerAngle = 0;wheels[1].steerAngle = 0;}}//车轮动画相关public  void WheelsAnimation(){for (int i = 0; i < wheels.Length ; i++){//获取当前空间的车轮位置 和 角度wheels[i].GetWorldPose(out wheelPosition, out wheelRotation);//赋值给wheelMesh[i].transform.position = wheelPosition;print(wheelRotation);wheelMesh[i].transform.rotation = wheelRotation * Quaternion .AngleAxis (90,Vector3 .forward );}}
}}}
}

🎶(B车辆优化——车身持续稳定的优化


WheelMove脚本 ——> CarMoveControl脚本 更改脚本名


😶‍🌫️速度属性实时转换


  • 每小时多少公里 和 每秒多少米的对应关系 ——1m/s = 3.6km/h

速度属性建议改成Int类型 ,float类型会上下浮动不准确

 //1m/s = 3.6km/hKm_H =(int)(rigidbody.velocity.magnitude * 3.6) ;Km_H = Mathf.Clamp( Km_H,0, 200 );   //油门速度为 0 到 200 Km/H之间
  • 相机测速 m/s
    在这里插入图片描述
  //相机监测实时速度Control = target.GetComponent<CarMoveControl>();speed = (int )Control.Km_H / 4;speed = Mathf.Clamp(0, 55,speed );   //对应最大200公里每小时
  • 添加四个轮子的实时速度,对应虚度属性,可以明显的观察四驱和二驱的汽车动力

在这里插入图片描述

    //车辆物理属性相关public void VerticalAttribute(){//1m/s = 3.6km/hKm_H =(int)(rigidbody.velocity.magnitude * 3.6) ;Km_H = Mathf.Clamp( Km_H,0, 200 );   //油门速度为 0 到 200 Km/H之间//显示每个轮胎的扭矩f_right = wheels[0].motorTorque;f_left  = wheels[1].motorTorque;b_right = wheels[2].motorTorque;b_left  = wheels[3].motorTorque;}

😶‍🌫️为车子添加下压力


知识百科: 什么是下压力
下压力是车在行进中空气在车体上下流速不一产生的,使空气的总压力指向地面从而增加车的抓地力.

速度越大,下压力越大,抓地更强,越不易翻车
在这里插入图片描述

  • 关键代码
  //-------------下压力添加-----------------//速度越大,下压力越大,抓地更强rigidbody.AddForce(-transform.up * downForceValue * rigidbody.velocity .magnitude );

😶‍🌫️质心的添加centerMess


知识百科:什么是质心?——质量中心
汽车制造商在设计汽车时会考虑质心的位置和重心高度,以尽可能减小质心侧偏角。 一些高性能汽车甚至会采用主动悬挂系统来控制车身侧倾,从而减小质心侧偏角,提高车辆的稳定性和操控性。

质量中心越贴下,越不容易翻
在这里插入图片描述

        //-------------质量中心同步----------------//质量中心越贴下,越不容易翻rigidbody.centerOfMass = CenterMass;
  • 手刹的添加
//手刹管理public void HandbrakControl(){if(InputManager.InputManagerment .handbanl ){     //后轮刹车wheels[2].brakeTorque  = brakVualue;wheels[3].brakeTorque  = brakVualue;}else{wheels[2].brakeTorque = 0;wheels[3].brakeTorque = 0;}}

😶‍🌫️轮胎的平滑度的显示


wheelhit.forwardSlip;用来观看刹车轮胎在滚动方向上打滑。加速滑移为负,制动滑为正
_______在这里插入图片描述

for (int i = 0; i < slip.Length; i++){WheelHit wheelhit;wheels[i].GetGroundHit(out wheelhit);slip[i] = wheelhit.forwardSlip; //轮胎在滚动方向上打滑。加速滑移为负,制动滑为正}               

🅰️

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


⭐【Unityc#专题篇】之c#进阶篇】

⭐【Unityc#专题篇】之c#核心篇】

⭐【Unityc#专题篇】之c#基础篇】

⭐【Unity-c#专题篇】之c#入门篇】

【Unityc#专题篇】—进阶章题单实践练习

⭐【Unityc#专题篇】—基础章题单实践练习

【Unityc#专题篇】—核心章题单实践练习


你们的点赞👍 收藏⭐ 留言📝 关注✅是我持续创作,输出优质内容的最大动力!


在这里插入图片描述


相关文章:

【Unity3D赛车游戏】【四】在Unity中添加阿克曼转向,下压力,质心会让汽车更稳定

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;Uni…...

Python爬虫requests判断请求超时并重新post/get发送请求

在使用Python爬虫中&#xff0c;你可以使用requestsimport requests #Python爬虫requests判断请求超时并重新post发送请求&#xff0c;proxies为代理 def send_request_post(url, data, headers , proxies , max_retries3, timeout5):retries 0while retries < max_retries…...

CSS中如何实现多列布局?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 多列布局&#xff08;Multi-column Layout&#xff09;⭐ column-count⭐ column-width⭐ column-gap⭐ column-rule⭐ column-span⭐ 示例⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧…...

【C++】string简单实用详解

本片要分享的内容是有关于string的知识&#xff0c;在这之前得介绍一下什么是STL&#xff1b; 目录 1.STL简单介绍 2. string简单介绍 3.string简单使用 3.1.string的定义 3.2.字符串的拼接 3.3.string的遍历 3.3.1.循环遍历 3.3.2.迭代器遍历 4.string的函数构造 1.…...

opencv 进阶16-基于FAST特征和BRIEF描述符的ORB(图像匹配)

在计算机视觉领域&#xff0c;从图像中提取和匹配特征的能力对于对象识别、图像拼接和相机定位等任务至关重要。实现这一目标的一种流行方法是 ORB&#xff08;Oriented FAST and Rotated Brief&#xff09;特征检测器和描述符。ORB 由 Ethan Rublee 等人开发&#xff0c;结合了…...

Unity 类Scene窗口相机控制

类Scene窗口相机控制 &#x1f354;效果 &#x1f354;效果 传送门&#x1f448;...

juc基础(三)

目录 一、读写锁 1、读写锁介绍 2、ReentrantReadWriteLock 3、例子 4、小结 二、阻塞队列 1、BlockingQueue 简介 2、BlockingQueue 核心方法 3、案例 4、常见的 BlockingQueue &#xff08;1&#xff09;ArrayBlockingQueue(常用) &#xff08;2&#xff09;Li…...

c语言函数指针和指针函数的区别,以及回调函数的使用。

函数指针是什么&#xff0c;函数指针本质也是指针&#xff0c;不过是指向函数的指针&#xff0c;存储的是函数的地址。 指针函数是什么,指针函数其实就是返回值是指针的函数&#xff0c;本质是函数。 函数指针是如何定义的呢&#xff0c;如下 void (*pfun)(int a,int b) 这…...

什么是服务端渲染?前后端分离的优点和缺点?

一.概念 服务端渲染简单点就是服务端直接返回给客户端一个完整的页面&#xff0c;也就是一个完整的html页面&#xff0c;这个页面上已经有数据了。说到这里你可能会觉得后端怎么写页面啊&#xff0c;而且服务端返回页面不是加载更慢吗&#xff1f;错了&#xff0c;因为我们现在…...

【Java】优化重复冗余代码的8种方式

文章目录 前言1. 抽取公用方法2. 抽工具类3. 反射4.泛型5. 继承与多态6.使用设计模式7.自定义注解(或者说AOP面向切面)8.函数式接口和Lambda表达式 前言 日常开发中&#xff0c;我们经常会遇到一些重复代码。大家都知道重复代码不好&#xff0c;它主要有这些缺点&#xff1a;可…...

rabbitmq卸载重新安装3.8版本

卸载之前的版本的rabbitmq 卸载rabbitmq 卸载前先停止rabbitmq服务 /usr/lib/rabbitmq/bin/rabbitmqctl stop查看rabbitmq安装的相关列表 yum list | grep rabbitmq卸载rabbitmq相关内容 yum -y remove rabbitmq-server.noarch 卸载erlang 查看erlang安装的相关列表 …...

MyBatis分页思想和特殊字符

目录 一、MyBatis分页思想 1.1 使用场景 1.2 代码演示 二、MyBatis特殊字符 2.1代码演示 一、MyBatis分页思想 1.1 使用场景 Mybatis分页应用场景&#xff1a; MyBatis是一个Java持久层框架&#xff0c;它提供了一种将SQL查询和结果映射到Java对象的简单方式。分页是MyBa…...

设计模式大白话——命令模式

命令模式 一、概述二、经典举例三、代码示例&#xff08;Go&#xff09;四、总结 一、概述 ​ 顾名思义&#xff0c;命令模式其实和现实生活中直接下命令的动作类似&#xff0c;怎么理解这个命令是理解命令模式的关键&#xff01;&#xff01;&#xff01;直接说结论是很不负责…...

[线程/C++(11)]线程池

文章目录 一、C实现线程池1. 头文件2. 测试部分 二、C11实现线程池1. 头文件2. 测试部分 一、C实现线程池 1. 头文件 #define _CRT_SECURE_NO_WARNINGS #pragma once #include<iostream> #include<string.h> #include<string> #include<pthread.h> #…...

VR防地质灾害安全教育:增强自然灾害知识,提高自我保护意识

VR防地质灾害安全教育系统是一种虚拟仿真技术&#xff0c;可以通过虚拟现实技术模拟地震、泥石流、滑坡等地质灾害的发生和应对过程&#xff0c;帮助人们提高应对突发自然灾害的能力。这种系统的优势在于可以增强自然灾害知识&#xff0c;提高自我保护意识&#xff0c;锻炼人们…...

Mybatis多对多查询案例!

在MyBatis中执行多对多查询需要使用两个主要表和一个连接表&#xff08;通常称为关联表&#xff09;来演示。在这个示例中&#xff0c;我们将使用一个示例数据库模型&#xff0c;其中有三个表&#xff1a;students、courses 和 student_courses&#xff0c;它们之间建立了多对多…...

Android OpenCV(七十五): 看看刚”转正“的条形码识别

前言 2021年,我们写过一篇《OpenCV 条码识别 Android 平台实践》,当时的条形码识别模块位于 opencv_contrib 仓库,但是 OpenCV 4.8.0 版本开始, 条形码识别模块已移动到 OpenCV 主仓库,至此我们无需自行编译即可轻松地调用条形码识别能力。 Bar code detector and decoder…...

数据结构——布隆计算器

文章目录 1.什么是布隆过滤器&#xff1f;2.布隆过滤器的原理介绍3.布隆过滤器使用场景4.通过 Java 编程手动实现布隆过滤器5.利用Google开源的 Guava中自带的布隆过滤器6.Redis 中的布隆过滤器6.1介绍6.2使用Docker安装6.3常用命令一览6.4实际使用 1.什么是布隆过滤器&#xf…...

金融学复习博迪(第6-9章)

第6章 投资项目分析 学习目的&#xff1a;解释资本预算&#xff1b;资本预算基本法则 资本预算过程包含三个基本要素&#xff1a; 一提出针对投资项目的建议 一对这些建议进行评价 一决定接受和拒绝哪些建议 6.1项目分析的特性 资本预算的过程中的基本单位是单个的投资项目。投…...

解决idea登录github copilot报错问题

试了好多方案都没用&#xff0c;但是这个有用&#xff0c; 打开idea-help-edit custonm vm options 然后在这个文件里面输入 -Dcopilot.agent.disabledtrue再打开 https://github.com/settings/copilot 把这个设置成allow&#xff0c;然后重新尝试登录copilot就行就行 解决方…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

【JavaSE】绘图与事件入门学习笔记

-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角&#xff0c;以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向&#xff0c;距离坐标原点x个像素;第二个是y坐标&#xff0c;表示当前位置为垂直方向&#xff0c;距离坐标原点y个像素。 坐标体系-像素 …...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域&#xff0c;高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表&#xff0c;以及基于它们实现的 Reactor 模式&#xff0c;为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...

.Net Framework 4/C# 关键字(非常用,持续更新...)

一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

虚拟电厂发展三大趋势:市场化、技术主导、车网互联

市场化&#xff1a;从政策驱动到多元盈利 政策全面赋能 2025年4月&#xff0c;国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》&#xff0c;首次明确虚拟电厂为“独立市场主体”&#xff0c;提出硬性目标&#xff1a;2027年全国调节能力≥2000万千瓦&#xff0…...

宇树科技,改名了!

提到国内具身智能和机器人领域的代表企业&#xff0c;那宇树科技&#xff08;Unitree&#xff09;必须名列其榜。 最近&#xff0c;宇树科技的一项新变动消息在业界引发了不少关注和讨论&#xff0c;即&#xff1a; 宇树向其合作伙伴发布了一封公司名称变更函称&#xff0c;因…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

Windows电脑能装鸿蒙吗_Windows电脑体验鸿蒙电脑操作系统教程

鸿蒙电脑版操作系统来了&#xff0c;很多小伙伴想体验鸿蒙电脑版操作系统&#xff0c;可惜&#xff0c;鸿蒙系统并不支持你正在使用的传统的电脑来安装。不过可以通过可以使用华为官方提供的虚拟机&#xff0c;来体验大家心心念念的鸿蒙系统啦&#xff01;注意&#xff1a;虚拟…...