关于射线批处理 RayCastCommand 使用
前言:API 用于实际解决问题中,批处理射线较为实用,数量大间隔大的使用较为轻松对于性能提升有较高的帮助,相对于射击功能、指定抓点功能等需要减少计算,对于性能消耗对比可见效果比较大
private NativeArray<RaycastCommand> rayCommands; private NativeArray<RaycastHit> rayCastHits; //以上两个都是高速数组能快速处理数据因为之后要利用多线程来进行射线计算 private List<Vector3> dirs; private List<float> distance; //射线距离必须减少偏差性的准确 int maxHits = 2, minCommandsPerJob = 10; //最大射线返回碰撞数据 最小工作指针数(需要研究 JobHandle 原理才能明白参数) //异步批量射线检测 { var rayPoints = DataController.Instance.RayPoints; int Count = rayPoints.Count; dirs = new List<Vector3>(); distance = new List<float>(); for (int i = 0; i < rayPoints.Count; i++) { dirs.Add(rayPoints[i] - this.transform.position); distance.Add(Vector3.Distance(this.transform.position, rayPoints[i])); } rayCastHits = new NativeArray<RaycastHit>(Count * maxHits + 1, Allocator.TempJob); rayCommands = new NativeArray<RaycastCommand>(Count, Allocator.TempJob); for (int i = 0; i < Count; i++) { var rayPose = rayPoints[i]; rayCommands[i] = new RaycastCommand(this.transform.position, dirs[i], distance[i], layerMask, maxHits); } job = RaycastCommand.ScheduleBatch(rayCommands, rayCastHits, minCommandsPerJob); //批处理 API 利用 JobHandle 进行并发处理 job.Complete(); if (JobHandle.CheckFenceIsDependencyOrDidSyncFence(job, default(JobHandle))) { for (int i = 0; i < rayCastHits.Length; i++) { var rayHit = rayCastHits[i]; if (rayHit.collider != null) { if (i >= DataController.Instance.terrainDataItems.Count) Debug.LogErrorFormat(" i{0} 比较一下 terrainDataItems{1} rayCastHits{2}", i, DataController.Instance.terrainDataItems.Count, rayCastHits.Length); else { if (rayHit.transform != null && Tags.Contains(rayHit.transform.tag)) DataController.Instance.terrainDataItems[i].ReciveRayCastHit(rayHit.point.x, 10000, rayHit.point.z); else DataController.Instance.terrainDataItems[i].ReciveRayCastHit(rayHit.point.x, rayHit.point.y, rayHit.point.z); } } } } rayCastHits.Dispose(); rayCommands.Dispose(); job = default; }
总结
1.要使用带网格渲染的物体
2.处理数据需要自己另行优化(集中较多数量的射线返回数据)
3.Struct 都是 栈中处理 很快数据就会消亡
4.返回的数据最好是快速处理 大量的数据不建议使用class 性能耗费高 ,struct 来进行数据存储
更新
射线点要精确 边角 容易返回无效的射线碰撞值
经过一段时间的使用和摸索,还有查阅资料,大批量的使用效率非常高效 坑也是 蛮多的
JobHandle 可以查阅Job System 相关信息
常见报错 >=m_BufferSize 这个在你的代码数据都设定好后 还会出的话一般是没什么问题 是 内部申请空间超过了 但是射线返回的数据仍然有数据
不吹 牛逼的说 利用这个 + A* 算法 都可以 做 一套 完整的 寻路功能了 批量高效的抓取坐标点制作 寻路数据