网站工信部本案,网络营销专业是学什么的,公司网站建设的作用与意义,厦门网站建设网页设计3D动态路障生成 介绍设计实现1.路面创建2.空物体的创建3.Create.cs脚本创建 总结 介绍
上一篇文章介绍了Mathf.Lerp的底层实现原理#xff0c;这里介绍一下跑酷类游戏的动态路障生成是如何实现的。 动态路障其实比较好生成#xff0c;但是难点在哪里#xff0c;如果都是平面… 3D动态路障生成 介绍设计实现1.路面创建2.空物体的创建3.Create.cs脚本创建 总结 介绍
上一篇文章介绍了Mathf.Lerp的底层实现原理这里介绍一下跑酷类游戏的动态路障生成是如何实现的。 动态路障其实比较好生成但是难点在哪里如果都是平面或者都是没有转弯的话还是比较好实现的如果动态路障的实现遇到了有上坡下坡或者有转弯的地方我们如何去处理这些拐角点和上下坡的旋转和位置呢
设计实现
简单说一下设计思路 路面的终点为坐标的原点0,0,0把我们的路面朝向Z轴的方向也就是说我们生成路障时只需要采用Z轴的深度即可。 我们在终点到起点之间创建多个空物体这个空物体用于判断创建的路障在哪两个空物体之间然后采用Lerp来进行插值运算使我们在拐角处和有坡度的位置生成正确旋转与位置的路障。 生成路障时自定义参数距离范围随机生成路障那么它的旋转角度和高度我们可以用上述两个空物体差值运算得到。
1.路面创建
下面是我简单的用Plane拼接出来的路面终点的位置为Unity的000 这里我全成长度为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/// 路障物体数组/// /summarypublic GameObject[] obstacles;/// summary/// 路障在道路上出现的开始位置/// /summarypublic float startLength 10;/// summary/// 路障距上一个路障的最小距离 /// /summarypublic float minLength 10;/// summary/// 路障距上一个路障的最大距离 /// /summarypublic float maxLength 20;/// summary/// 与路面相贴合的路线上的脚本组件 /// /summaryprivate waypoints wayPoints;void Awake(){wayPoints GameObject.Find(waypoints).GetComponentwaypoints(); }// Use this for initialization void Start(){//创建路障GenerateObstacle(); }/// summary/// 创建路障/// /summaryvoid 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 namez/param/// returns/returnsint 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()的用法如果有不明白的可以看我上一篇文章