>科技>>正文

【厚积薄发】如何获取Unity导航系统中某点的高度

原标题:【厚积薄发】如何获取Unity导航系统中某点的高度

这是第115篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题,建议阅读时间10分钟,认真读完必有收获。

导航网格

Q:我们现在正在做基于Unity自带导航系统的寻路逻辑,但是不知道如何获得Unity自带导航模型在某一点的高度,就没法正确设置角色y值。目前想到的办法是自己生成一套Heightmap和一套导航模型,先对Heightmap进行高度查询,Heightmap查询失败再进行导航模型的射线检测。但是这么做会增加一些内存,不知道Unity有没有内置的方法去获得导航某点高度?

A1:1)之前都是用的NavMesh.SamplePosition,从较高的点投射线,在射线上取点作为球心调用SamplePosition。

2)还一种方法是,让美术做Mesh Collider,专门用来接收测试高度的射线。

感谢史云柯@UWA问答社区提供了回答,详细可前往社区了解

A2:之前做过类似的东西,但是没有用NavMesh,所以不敢肯定效率是否比NavMesh.SamplePosition好。

方案:在Editor中做预处理,将场景中带碰撞的对象合并成一个Mesh(因为有些不是MeshCollider,而是Box、Sphere、Capsule,这种Mesh要自己生成),然后将问题转化为射线与三角面求交的问题(对于MeshCollider的射线检测,本质上就是这个问题)。

当然这是最基本的,更进一步:

1)相邻的面如果法线相近,就合并成一个多边形,于是又转化为射线与多边形求交的问题。

2)为多边形计算AABB,先用AABB进行检测。

3)对多边形进行排序,面积大的优先进行检测。

4)未实现的:将多边形投影到XZ平面上,y值只作存储,不参与求交运算。

5)未实现的:可以尝试使用四叉树进行空间分割。

感谢凯奥斯@UWA问答社区提供了回答

A3:以前也遇到过这个问题,我尝试过各种方式,Unity并没有给出很好的解决方案,直接调用Navmesh.SamplePosition是很容易取到错误的位置,因为它是按照球体碰撞来获取最近的点,而且这个函数随着半径增加,性能急剧下降,测试过在1.5米半径下消耗是差不多的。所以获取高度,最好还是以物理碰撞未准,那么生成这个Mesh碰撞才是关键,体质可以使用Navmesh.CalculateTriangulation这个函数去获取已经刷好的Navmesh区域,生成Mesh。可以参考:

感谢简简单单@UWA问答社区提供了回答

欢迎大家转至社区进行进一步交流

UI

Q:在UWA Mono堆内存分析报告中发现我们逻辑代码中我们发现Text.get_cachedTextGenerator 这个函数居然占用了将近6MB的堆内存,请问这里可以怎么优化?

UWA:每个Text组件都会执行一次构造函数,即TextGenerator…ctor。图片中该堆内存较高,说明题主项目中的Text组件太多了,建议对UI界面中类似的信息进行详细排查。

此问答由UWA提供,欢迎大家转至社区进行进一步交流

渲染

Q:GPU Instancing能够支持每个实例采样不同的纹理吗?我试了下类似这样的做法,但是编译不过:

UNITY_DEFINE_INSTANCED_PROP(sampler2d, _MainTex)

A:这是不被支持的,纹理不能被用来作为instanced的属性…建议题主了解下Texture2DArray,可以通过脚本创建一个Texture2DArray,然后把Array的Index作为instanced的属性传到Shader中,这样就可以通过不同的index来采样不同的纹理了。

感谢Bunnyisrunning@UWA问答社区提供了此回答,欢迎大家转至社区进行进一步交流

编辑器

Q:有什么好办法可以在脚本的某个值在Inspector里被修改的时候触发一个函数吗?主要是希望在改数值的时候,做一些检测和提醒的功能。

A1:题主可以用OnValidate这个事件(事件链接前往社区了解)

感谢Bunnyisrunning@UWA问答社区提供了回答

A2:题主可以了解下OnInspectorGUI

或者https://github.com/LMNRY/SetProperty

感谢凯奥斯@UWA问答社区提供了回答

A3:重写Inspector视图,绑定脚本。

感谢凌乱@UWA问答社区提供了回答

欢迎大家转至社区进行进一步交流

逻辑代码

Q:自己写的插件在IL2CPP下出现问题。

先上代码:

打了一个so放Plugins/Android/libs下。在Mono下调用ftcode能正常得到想要的结果,即传进去一个20长度的byte数组,经过加密后能正常得到20长度byte数组,但是在IL2CPP下调用这个bytes的长度就变成了1。 这个是转CPP后的Bug吗? 有没有人遇到过呀?

A:换了参数

int ftcode(int seed, int type, void* data, int length)

调用

感谢题主Let_Go@UWA问答社区分享了经验,欢迎大家转至社区进行进一步交流

今天的分享就到这里。当然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题也许都只是冰山一角,我们早已在UWA问答网站上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入,也许你的方法恰能解别人的燃眉之急;而他山之“石”,也能攻你之“玉”。返回搜狐,查看更多

责任编辑:

声明:该文观点仅代表作者本人,搜狐号系信息发布平台,搜狐仅提供信息存储空间服务。
阅读 ()
投诉
免费获取
今日推荐