【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#专题篇】—核心章题单实践练习


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


在这里插入图片描述


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/51688.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++实现字符串的逆置

目录 C和C的区别 【1】C对C的扩充 【2】C对C的兼容 第一个C程序 【1】hello world 【2】cout标准输出流对象 i&#xff09;介绍 ii&#xff09;运算 iii&#xff09;cout的使用 iv&#xff09;使用cout指定格式的输出 练习&#xff1a;1、输出斐波那契的前10项。 【3】…

《Linux从练气到飞升》No.17 进程创建

&#x1f57a;作者&#xff1a; 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux菜鸟刷题集 &#x1f618;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 &#x1f3c7;码字不易&#xff0c;你的&#x1f44d;点赞&#x1f64c;收藏❤️关注对我真的…

VB超市配送运输管理系统设计与实现

摘要: 连锁经营从九十年代初进入中国市场以来,由于具有批量进货、集中配送、统一管理、统一价格的优点,表现出良好的发展势头。发展连锁业,配送中心的建设是关键。本文以我国某大型连锁超市的配送中心信息化管理为实际背景,介绍了连锁超市配送中心运输管理信息系统设计开发…

开学需要买哪些电容笔?ipad可以用的手写笔

因为iPad的功能亮眼&#xff0c;让iPad的用户越来越多&#xff0c;并且越来越受欢迎。用来画画、做笔记都很有用&#xff0c;但要是用来看电视、打游戏的话&#xff0c;使用价值就显得低了。如果你不想买一支价格不菲的苹果电容笔&#xff0c;或是只是想要日常用于书写记录&…

Day04-Vue基础-监听器-双向绑定-组件通信

Day04-Vue基础-监听器-双向绑定-组件通信 一 侦听器 语法一 <template><div>{{name}}<br><button @click="update1">修改1</button><

【云原生】Docker Cgroups资源控制管理

目录 一、cgroups简介 cgroups有四大功能&#xff1a; 二、cpu时间片的概念 三、对CPU使用的限制 3.1 设置CPU使用率上限 &#xff08;1&#xff09;查看容器的默认CPU使用限制 &#xff08;2&#xff09;进行压力测试 &#xff08;3&#xff09;创建容器时设置CPU使用时…

Linux下套接字TCP实现网络通信

Linux下套接字TCP实现网络通信 文章目录 Linux下套接字TCP实现网络通信1.引言2.具体实现2.1接口介绍1.socket()2.bind()3.listen()4.accept()5.connect() 2.2 服务器端server.hpp2.3服务端server.cc2.4客户端client.cc 1.引言 ​ 套接字(Socket)是计算机网络中实现网络通信的一…

Linux笔记--Ubuntu设置sftp服务

目录 1--修改配置文件 2--注销代码 3--更改代码 4--重启服务 1--修改配置文件 vim /etc/ssh/sshd_config 2--注销代码 ① 注销&#xff1a; Subsystem sftp /usr/libexec/openssh/sftp-server ② 更改为&#xff1a; Subsystem sftp internal-sftp 3--更改代码 Per…

浙大陈越何钦铭数据结构07-图6 旅游规划

题目: 有了一张自驾旅游路线图&#xff0c;你会知道城市间的高速公路长度、以及该公路要收取的过路费。现在需要你写一个程序&#xff0c;帮助前来咨询的游客找一条出发地和目的地之间的最短路径。如果有若干条路径都是最短的&#xff0c;那么需要输出最便宜的一条路径。 输入…

Java——面向对象编程思想

前言 如果有人问你&#xff0c;C和Java的区别是什么呢&#xff1f; 我想大部分人肯定脱口而出的是&#xff1a;C是面向过程的&#xff0c;Java是面向对象的。 那如何理解面向过程和面向对象呢&#xff1f; 首先&#xff0c;面向过程和面向对象都是编程思想。 ①面向过程&#…

【3Ds Max】可编辑多边形“边界”层级的简单使用

目录 示例 &#xff08;1&#xff09;挤出 &#xff08;2&#xff09;插入顶点 &#xff08;3&#xff09;切角 &#xff08;4&#xff09;利用所选内容创建图形 &#xff08;5&#xff09;封口 &#xff08;6&#xff09;桥 示例 这里我们首先创建一个长方体&#xff…

【Java面试】指令重排引发问题及解决方案

一 指令重排引发的问题 什么是指令重排&#xff1f; 指令重排是指在程序执行过程中&#xff0c;为了优化性能&#xff0c;编译器或处理器可能会重新安排代码指令的执行顺序&#xff0c;但要求不改变程序的最终结果。 在多线程环境中&#xff0c;指令重排可能会引发一些问题&a…

C#使用xamarin进行跨平台开发

使用 Xamarin 进行跨平台开发可以使用 C# 和 .NET 平台来开发移动应用程序&#xff0c;同时将代码在多个主要移动操作系统上运行&#xff0c;包括 Android 和 iOS。以下是在 C# 中使用 Xamarin 进行跨平台开发的一般步骤&#xff1a; 安装 Xamarin&#xff1a; 在开始之前&…

Java基础之IO流File类创建及删除

1.File类概述及构造方法 2.File类创建功能 文件创建成功&#xff01; 如果文件不存在&#xff0c;就创建文件&#xff0c;并返回true 如果文件存在&#xff0c;就不创建文件&#xff0c;并返回false 如果文件夹不存在&#xff0c;就创建文件夹&#xff0c;并返回true 如果文件…

html学习第2篇---标签(1)

html学习第2篇---标签 1、标题标签h1---h62、段落标签p3、换行标签br4、文本格式化标签5、div标签和span标签6、图像标签img6.1、图像属性6.2、相对路径、绝对路径 7、超链接标签a7.1、属性7.2、分类 8、注释标签和特殊字符8.1、注释8.2、特殊字符 1、标题标签h1—h6 为了使网…

【Unity学习笔记】DOTween(2)官方案例

本文中大部分内容学习来自DOTween官方文档 此处无法展示动图&#xff08;懒得录GIF&#xff09;&#xff0c;请下载官方案例场景自行学习 文章目录 场景1 基本补间场景2 动态补间场景3 Shader修改场景4 路径拟合运动场景5 序列播放场景6 UGUI 场景1 基本补间 案例一展示了最基…

Python操作sql,备份数据库

1、批量执行sql import pymysql# 执行批量的 SQL 语句 def executeBatchSql(cursor, sqlStatements):for sql in sqlStatements:try:cursor.execute(sql)print(Executed SQL statement:, sql)except Exception as e:print(Error executing SQL statement:, e)# 创建数据库连接…

AMBA总线协议(0)——目录与传送门

一、AMBA总线协议 Arm高级微控制器总线架构&#xff08;Advanced Microcontroller Bus Architecture&#xff0c;AMBA&#xff09;是一种开放式标准片上互联规范&#xff0c;用于连接和管理片上系统&#xff08;System on Chip,Soc&#xff09;中的功能块。 AMBA是一种广泛用于…

设计模式-代理模式

代理模式 ● 为对象提供一个代理类&#xff0c;增强该对象的方法&#xff0c;控制对这个对象的访问 ● 静态代理和动态代理&#xff1a;静态代理就是编译的时候就已经确定&#xff0c;而动态代理就是运行时才会生成 静态代理的使用场景 缓存代理 ● 提供数据的缓存功能&…

python字符串处理15题-刷题

题目一&#xff1a;最长无重复子串长度 给定一个字符串&#xff0c;找出其中不含有重复字符的最长子串的长度。 示例&#xff1a; 输入: "abcabcbb" 输出: 3 解释: 最长无重复子串是 "abc"&#xff0c;长度为 3。 解答&#xff1a; def length_of_longest…