3D动态路障生成

3D动态路障生成

  • 介绍
  • 设计实现
    • 1.路面创建
    • 2.空物体的创建
    • 3.Create.cs脚本创建
  • 总结

介绍

上一篇文章介绍了Mathf.Lerp的底层实现原理,这里介绍一下跑酷类游戏的动态路障生成是如何实现的。
动态路障其实比较好生成,但是难点在哪里,如果都是平面或者都是没有转弯的话还是比较好实现的,如果动态路障的实现遇到了有上坡下坡或者有转弯的地方我们如何去处理这些拐角点和上下坡的旋转和位置呢?

设计实现

简单说一下设计思路
路面的终点为坐标的原点(0,0,0),把我们的路面朝向Z轴的方向,也就是说我们生成路障时,只需要采用Z轴的深度即可。
我们在终点到起点之间创建多个空物体,这个空物体用于判断创建的路障在哪两个空物体之间,然后采用Lerp来进行插值运算,使我们在拐角处和有坡度的位置生成正确旋转与位置的路障。
生成路障时,自定义参数距离范围随机生成路障,那么它的旋转角度和高度我们可以用上述两个空物体差值运算得到。

1.路面创建

下面是我简单的用Plane拼接出来的路面终点的位置为Unity的(0,0,0)
这里我全成长度为300,也就是说图中的起点位置为(x,x,-300)
在这里插入图片描述

2.空物体的创建

在Road路面里面创建一个waypoints的空物体,将我们后面创建的空物体都放在里面,
我们可以在整个路面上创建无数个空物体,但是空物体的Z轴旋转和Y轴的高度是要跟路面保持一致的,因为我们后面要用这个空物体的position和rotation来进行插值运算得到路障的位置和旋转角度,这里空物体创建的越多,路障贴合路面的坡度和旋转就更加精准。最后创建一个Waypoints的脚本挂载到waypoints上去获取我们所有创建的空物体,可以用OnDrawGizmos()去绘制出来方便我们看。

创建的位置如下
在这里插入图片描述
这里可以看到我把每一个点的Z轴旋转角度都贴合了路面

脚本如下:

[ExecuteInEditMode]public class waypoints : MonoBehaviour {public Transform[] points;void OnDrawGizmos(){for (int i = 0; i < points.Length; i++){Gizmos.color = Color.red;Gizmos.DrawWireSphere(points[i].transform.position, 5);}}}

3.Create.cs脚本创建

using System.Collections;using System.Collections.Generic;using UnityEngine;public class Create : MonoBehaviour {/// <summary>/// 路障物体数组/// </summary>public GameObject[] obstacles;/// <summary>/// 路障在道路上出现的开始位置/// </summary>public float startLength = 10;/// <summary>/// 路障距上一个路障的最小距离  /// </summary>public float minLength = 10;/// <summary>/// 路障距上一个路障的最大距离  /// </summary>public float maxLength = 20;/// <summary>/// 与路面相贴合的路线上的脚本组件  /// </summary>private waypoints wayPoints;void Awake(){wayPoints = GameObject.Find("waypoints").GetComponent<waypoints>(); }// Use this for initialization  void Start(){//创建路障GenerateObstacle(); }/// <summary>/// 创建路障/// </summary>void GenerateObstacle(){//当前道路在场景中的起始Z坐标  float startZ = transform.position.z - 300;//当前道路在场景中的结束Z坐标  float endZ = transform.position.z;//将要产生路障的Z坐标float z = startZ + startLength;while (true){//每隔多少米的距离产生一个路障  z += Random.Range(minLength, maxLength);//如果将要产生路障的位置超出了这条道路则退出路障产生循环,否则产生路障 if (z > endZ)                            {break;}else{//方法计算路障位置坐标Vector3 position = GetWayPos(z);//方法计算路障旋转坐标Vector3 rotation = GetWayRotate(z);//产生一个从路障数组里取路障的随机序数  int obsIndex = Random.Range(0, obstacles.Length);//实例化路障 Instantiate(obstacles[obsIndex], position, Quaternion.Euler(rotation.x, rotation.y, rotation.z)); }}}/// <summary>/// 获取转折点的集合索引值/// </summary>/// <param name="z"></param>/// <returns></returns>int GetPointIndex(float z){//在道路上设置的转折点的集合  Transform[] points = wayPoints.points;//转折点在集合中的序数号  int index = 0;for (int i = 0; i < points.Length - 1; i++){//根据要插入路障的Z值在集合中寻找在哪两个点之间,找到后记下序数号  if (z >= points[i].position.z && z <= points[i + 1].position.z){index = i;break;}}return index;}Vector3 GetWayPos(float z){int index = GetPointIndex(z);//使用Lerp函数计算出插入路障处的空间坐标值  return Vector3.Lerp(wayPoints.points[index + 1].position, wayPoints.points[index].position, (z - wayPoints.points[index + 1].position.z) / (wayPoints.points[index].position.z - wayPoints.points[index + 1].position.z));}Vector3 GetWayRotate(float z){int index = GetPointIndex(z);return Vector3.Lerp(wayPoints.points[index + 1].eulerAngles, wayPoints.points[index].eulerAngles, (z - wayPoints.points[index + 1].position.z) / (wayPoints.points[index].position.z - wayPoints.points[index + 1].position.z));}}

创建完成结果如下:
在这里插入图片描述

总结

本片文章主要讲解Mathf.Lerp()的用法,如果有不明白的可以看我上一篇文章

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

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

相关文章

HTML使用JavaScript的三种方式

要使用 JavaScript&#xff0c;你可以在 HTML 文件中的 <script> 标签中编写代码&#xff0c;或者将代码保存到一个单独的 .js 文件中并在 HTML 文件中引入。以下是一些常用的 JavaScript 使用方式&#xff1a; 内联 JavaScript&#xff1a;在 HTML 文件的 <script&g…

爬虫实战-微博评论爬取

简介 最近在做NLP方面的研究&#xff0c;以前一直在做CV方面。最近由于chatgpt&#xff0c;所以对NLP就非常感兴趣。索性就开始研究起来了。 其实我们都知道&#xff0c;无论是CV方向还是NLP方向的模型实现&#xff0c;都是离不开数据的。哪怕是再先进的代码&#xff0c;都是…

007、控制流

先看下本篇学习内容&#xff1a; 通过条件来执行 或 重复执行某些代码 是大部分编程语言的基础组成部分。在Rust中用来控制程序执行流的结构主要就是 if表达式 与 循环表达式。 1. if表达式 if表达式允许我们根据条件执行不同的代码分支。我们提供一个条件&#xff0c;并且做出…

Bytebase:统一数据库 CI/CD 解决方案 | 开源日报 No.128

bytebase/bytebase Stars: 7.9k License: NOASSERTION Bytebase 是一个数据库 CI/CD 解决方案&#xff0c;为开发人员和 DBA 提供统一的工具来管理不同数据库系统的开发生命周期。其主要功能包括标准化操作流程、SQL 代码审查、GitOps 集成以及数据访问控制等。关键特性和核心…

C#线程基础(线程启动和停止)

目录 一、关于线程 二、示例 三、生成效果 一、关于线程 在使用多线程前要先引用命名空间System.Threading&#xff0c;引用命名空间后就可以在需要的地方方便地创建并使用线程。 创建线程对象的构造方法中使用了ThreadStart()委托&#xff0c;当线程开始执行时&#xff0c…

【ArcGIS微课1000例】0084:甘肃积石山地震震中100km范围内历史灾害点分布图(2005-2020)

甘肃积石山地震震中100km范围内历史灾害点分布图(2005-2020)。 文章目录 一、成果预览二、实验数据三、符号化四、地图整饰一、成果预览 本实验最终效果图如下所示: 二、实验数据 以下数据可以从本专栏配套的实验数据包中0084.rar中获取。 1. 历史灾害数据。为2005-2020时…

微信小程序-入门

文章目录 微信小程序1. 基础知识1.1 小程序的定义和特点1.2 小程序的架构1.3 小程序的目录结构和文件类型1.4 小程序源文件解析1.4.1 app.json文件1.4.2 project.config.json文件1.4.3 sitemap.json文件 微信小程序 微信小程序开发工具下载&#xff1a; 微信官方文档&#xf…

【深度学习-图像分类】02 - AlexNet 论文学习与总结

论文地址&#xff1a;ImageNet Classification with Deep Convolutional Neural Networks 论文学习 1. 摘要 本研究训练了一个大型深度卷积神经网络&#xff08;CNN&#xff09;&#xff0c;用于对ImageNet LSVRC-2010比赛中的1.2百万高分辨率图像进行分类&#xff0c;这些图…

十大排序总结之——冒泡排序、插入排序

同样&#xff0c;这两几乎也是被淘汰了的算法&#xff0c;尽管它们是稳定的&#xff0c;但是时间复杂度没人喜欢&#xff0c;了解一下就好&#xff0c;没啥好说的&#xff0c;注意最后一句话就行了 一&#xff0c;冒泡排序 1. 算法步骤 共n-1趟&#xff0c;谁两敢冒泡就换了…

Stable Diffusion API入门:简明教程

Stable Diffusion 是一个先进的深度学习模型&#xff0c;用于创造和修改图像。这个模型能够基于文本描述来生成图像&#xff0c;让机器理解和实现用户的创意。使用这项技术的关键在于掌握其 API&#xff0c;通过编程来操控图像生成的过程。 在探索 Stable Diffusion API 的世界…

相机内参标定理论篇------相机模型选择

相机种类&#xff1a; 当拿到一款需要标定内参的相机时&#xff0c;第一个问题就是选择那种的相机模型。工程上相机类型的划分并不是十分严格&#xff0c;一般来说根据相机FOV可以把相机大概分为以下几类&#xff1a; 长焦相机&#xff1a;< 标准相机&#xff1a;~&…

2022年全国职业院校技能大赛(高职组)“云计算”赛项赛卷①第一场次:私有云

2022年全国职业院校技能大赛&#xff08;高职组&#xff09; “云计算”赛项赛卷1 第一场次&#xff1a;私有云&#xff08;30分&#xff09; 目录 2022年全国职业院校技能大赛&#xff08;高职组&#xff09; “云计算”赛项赛卷1 第一场次&#xff1a;私有云&#xff0…

千里马2023年终总结-android framework实战

背景&#xff1a; hi粉丝朋友们&#xff1a; 2023年马上就过去了&#xff0c;很多学员朋友也都希望马哥这边写个年终总结&#xff0c;因为这几个月时间都忙于新课程halsystracesurfaceflinger专题的开发&#xff0c;差点都忘记了这个事情了&#xff0c;今天特别花时间来写个bl…

最优化方法Python计算:无约束优化应用——神经网络回归模型

人类大脑有数百亿个相互连接的神经元&#xff08;如下图(a)所示&#xff09;&#xff0c;这些神经元通过树突从其他神经元接收信息&#xff0c;在细胞体内综合、并变换信息&#xff0c;通过轴突上的突触向其他神经元传递信息。我们在博文《最优化方法Python计算&#xff1a;无约…

SpringMVC框架

SpringMVC 三层架构MVC模式SpringMVC入门案例总结 三层架构 表现层&#xff08;web&#xff09; 页面数据的收集&#xff0c;产出页面 业务逻辑层&#xff08;service&#xff09; 业务处理 数据访问层&#xff08;Dao&#xff09; 数据持久化 MVC模式 SpringMVC 基于Java…

影视后期:PR 调色处理,灰片还原,校色偏色素材

灰片还原 确定拍摄灰片的相机型号品牌官网下载专用log文件LUT-浏览-导入slog3分析亮部波形-增加画面对比分析矢量示波器-提高整体饱和 校正LUT可以将前期拍摄的log色彩模式的视频转换为成709色彩模式&#xff0c;即将灰度视频转换为正常效果(灰片还原) 各个相机有对应的校正L…

开源预约挂号平台 - 从0到上线

文章目录 开源预约挂号平台 - 从0到上线演示地址源码地址可以学到的技术前端技术后端技术部署上线开发工具其他技术业务功能 项目讲解前端创建项目 - 安装PNPM - 使用VSCODE - 安装插件首页顶部与底部 - 封装组建 - 使用scss左右布局中间内容部分路由 - vue-routerBANNER- 走马…

RFC6749-OAuth2.0

前言 最近在项目中需要实现SSO(单点登录)功能,以实现一处注册,即可在任何平台之间登录的功能。我们项目中并没有直接对接第三方认证系统而是通过集成keycloak 完成一系类安全协议的对接工作。如果我们在代码级别自己完成各种安全协议的对接是一项十分大的工程。不仅要走统一的…

jsp介绍

JSP 一种编写动态网页的语言&#xff0c;可以嵌入java代码和html代码&#xff0c;其底层本质上为servlet,html部分为输出流&#xff0c;编译为java文件 例如 源jsp文件 <% page contentType"text/html; charsetutf-8" language"java" pageEncoding&…

Django 学习教程-介绍与安装

系列 Django 学习教程- Hello world入门案例-CSDN博客 介绍 Django 是一个由 Python 编写用于Web 应用程序开发的高级 Python Web 框架 Django 提供了一套强大的工具&#xff08;无需重新发明轮子&#xff09;&#xff0c;使得开发者能够快速构建 Web 网站。 Django 采用了…