当前位置:   article > 正文

基于Unity3D的自动寻路车辆模拟_unity 车辆导引线模拟

unity 车辆导引线模拟

案例展示

 

1、开发背景

仿真测试可以在开发的早期,在即便实际处理器控制器和实车都没有ready的情况下——依然能对算法进行测试,尽早发现bug,尽早解决bug,而不把过多的bug带到实车测试中去。

2、开发工具的基本使用

本项目开发工具选择Unity3D(2020.3.30f),开发语言选择C#

3、项目准备工作:导入素材搭建场景

选取我们需要的场景和车的模型,这里我们可以使用unity自带的Asset Store

 在商店页面搜索Car,筛选中选择免费

 这里会给我们展示出其他用户提前创建好的模型,同理搜索Road筛选出我们需要的道路。

首先导入我们的道路素材

Hierarchy中创建一个空物体,命名为Car,Transform中,Reset位置,从我们的素材中导入汽车的预制体作为子物体。

这里需要注意的是,我们的赛车模型,主要是靠车轮碰撞器来进行移动,所以我们需要将赛车的预制体模型拆分为汽车本体以及WheelMesh

首先结储预制体子物体的关联,将四个车轮放置在WheelMesh下。

继续创建一个空物体命名为WheelColider车轮碰撞体。

 4、摄像机跟随

摄像机跟随在该项目中有两种方式,最简单的方式就是直接将摄像机拖动到Car物体上,但是这样造成的问题是摄像机的移动不会十分平滑。

为了实现更加真实的场景,我们需要方式二对相机挂载脚本。

创建Folleow脚本,思路如下:

先确认好,相机初始合适的第三人称视角位置。

首先创建一个目标位置的变量,该变量通过查找标签为Player的物体获取位置。

定义一个临时变量,作为相机和车的固定距离。再定义一个临时变量用于存放摄像机位置。

固定位置变量(按照初始合适视角定义),摄像机位置等于车的位置加上固定距离。

最后让摄像机看着汽车尾部即可。

注意:这里需要将本地坐标转为世界坐标。

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class Follow : MonoBehaviour
  5. {
  6. private Transform targetPos;//跟随的目标
  7. private Vector3 offsetPos;//固定位置
  8. private Vector3 tempPos;//临时变量
  9. // Start is called before the first frame update
  10. void Start()
  11. {
  12. offsetPos = new Vector3(0,3,-6);
  13. targetPos = GameObject.FindGameObjectWithTag("Player").transform;
  14. }
  15. // Update is called once per frame
  16. void FixedUpdate()
  17. {
  18. tempPos = targetPos.position + targetPos.TransformDirection(offsetPos);
  19. transform.position = Vector3.Lerp(transform.position, tempPos, Time.fixedDeltaTime * 3);
  20. transform.LookAt(targetPos);
  21. }
  22. }

 5、车轮碰撞体的添加

首先为Car添加Rigidbody(刚体组件)在这里要注意车的质量要符合实际情况,否则会抖动或者被弹飞,Boxcolider(碰撞体组件),这里初始的Boxcolider比较小,范围不够大,我们需要手动编辑一下包含车头车尾即可,不要碰撞到轮胎

 在WheelColider的空物体中创建LF,添加wheel Colider组件,并调整到左前轮的位置和轮胎大小一致即可

 同理为四个轮子都添加WheelColider命名为LF、RF、LB、RB。

 注意:一定要保持WheelColider和轮胎高度的一致否则会造成抖动。

6、控制赛车的移动

创建一个脚本挂载到我们的车上,思路如下:

创建我们的车轮模型变量WheelMesh,创建WheelColider变量,定义最大角度,最大扭矩。

使用键盘操作类,

 1.Vertical                        对应键盘上面的上下箭头,当按下上或下箭头时触发

 2.Horizontal                    对应键盘上面的左右箭头,当按下左或右箭头时触发

float v = Input.GetAxisRaw("Vertical");

float v=h = Input.GetAxisRaw("Horizontal ");

按下向上方向键,返回值为1.0

按下向下方向键,返回值为0,继续按下返回值为-1.0
当在游戏运行的时候,按下你设置好的键盘就会返回 1和-1这两个值

遍历车轮碰撞体中每一个车轮最大扭矩×h即可实现车的前进和后退。

转弯的前轮是遍历车轮碰撞体中前两个车轮,让前两个车轮转动v×最大角度

6、赛车的车轮转动效果

赛车的车轮在运动的过程中需要实现滚动的效果。遍历模型中的每一个车轮,所有轮子都绕着X轴旋转,rpm为转速。
 

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class Control : MonoBehaviour
  5. {
  6. // Start is called before the first frame update
  7. private MeshRenderer[] wheelMesh;
  8. private WheelCollider[] wheel;
  9. private float maxAngle;//转弯最大角度
  10. private float maxToque;//扭矩
  11. private float h, v;
  12. void Start()
  13. {
  14. maxAngle = 30;
  15. maxToque = 1000;
  16. wheelMesh = transform.GetChild(0).GetComponentsInChildren<MeshRenderer>();
  17. wheel = transform.GetChild(1).GetComponentsInChildren<WheelCollider>();
  18. }
  19. // Update is called once per frame
  20. void Update()
  21. {
  22. h = Input.GetAxis("Horizontal");
  23. v = Input.GetAxis("Vertical");
  24. if (Mathf.Abs(h) == 0 && Mathf.Abs(v) == 0) return;
  25. Move();
  26. }
  27. private void Move()//车辆移动
  28. {
  29. for (int i = 0; i < 2; i++)
  30. {
  31. wheel[i].steerAngle = h * maxAngle;
  32. }
  33. foreach (var o in wheel)
  34. {
  35. o.motorTorque = maxToque * v;
  36. }
  37. for (int i = 0; i < 4;i++)
  38. {
  39. wheelMesh[i].transform.localRotation = Quaternion.Euler(wheel[i].rpm*360/60,wheel[i].steerAngle,0);
  40. }
  41. }
  42. }

7、实现赛车的Astar寻路导航

 AStar算法是一种静态路网中求解最短路径最有效的直接搜索方法。在包含各种障碍物的地图中,为游戏角色的移动,寻找一条到目标地点最短路径。

AStar的核心在于将游戏背景分为一个又一个格子,每个格子有自己的靠谱值,然后通过遍历起点的格子去找到周围靠谱的格子,接着继续遍历周围…… 最终找到终点。

使用Unity自带的Navigation寻路组件,新建一个空物体作为我们的目的地,将Road设置为静态。

在导航栏中选择Windows->Navigation打开 Bake 烘培,蓝色部分即为我们烘培的可行使区域。

 为Car添加NavMeshAgent组件。

 为了实现寻路轨迹展示,添加LineRenderer组件,用于在Game视图中画线段。

首先需要设置Materials否则材质会丢失。

 新建一个Navigation的C#脚本挂载到Car上,并选择好我们的目的地。

  1. using UnityEngine;
  2. using UnityEngine.AI;
  3. using System.Collections;
  4. public class Navigation : MonoBehaviour
  5. {
  6. public Transform TargetObject = null;
  7. void Start()
  8. {
  9. if (TargetObject != null)
  10. {
  11. GetComponent<NavMeshAgent>().destination = TargetObject.position;
  12. }
  13. }
  14. void Update()
  15. {
  16. }
  17. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/98884
推荐阅读
相关标签
  

闽ICP备14008679号