unity 判断物品是否出现在角色面前

来源:互联网 发布:淘宝刹那数码2店怎么样 编辑:程序博客网 时间:2024/05/22 12:49

有关这个问题,大致提两种思路,其实原理也都类似

1、使用角度:首先计算角色和物品的距离,是在附近的距离范围内(至于多少算近,这个自己定义好距离),使用Vector3.Distance,如果是在附近,然后计算角色和物品的角度使用Vector3.Angle计算是否在角色的视野范围内(至于角度,也是自己觉得多少度算合适就行)

下面见代码,代码是lua写的,我就不改了,和C#类似

function GetInSightBoxes(hero)local newBoxes = {}
local pos = hero:GetPosition()local cameraController = hero.cameraControllerlocal lookForward = cameraController.cameraTrans.forwardfor uid, box in pairs(Boxes) dolocal dist = Vector3.Distance(Vector3(box.position.x, 0, box.position.z), Vector3(pos.x, 0, pos.z))if dist < 5 then    box.distance = dist    local toOther = Vector3(box.position.x, 0, box.position.z) - Vector3(pos.x, 0, pos.z)    local angle = Vector3.Angle(toOther, lookForward)    if angle < 45 then newBoxes[uid] = box    endendendreturn newBoxesend

2、使用点乘 ,和上面类似,范围值是(-1,1)

-- 得到角色附近 面前的物品function GetInSightBoxes(hero)local newBoxes = {}local pos = hero:GetPosition()local cameraController = hero.cameraControllerlocal forward  = cameraController.cameraTrans:TransformDirection(Vector3.forward)for uid, box in pairs(Boxes) dolocal dist = Vector3.Distance(Vector3(box.position.x, 0, box.position.z), Vector3(pos.x, 0, pos.z))if dist < 5 then    box.distance = dist    local toOther = Vector3(box.position.x, 0, box.position.z) - Vector3(pos.x, 0, pos.z)    local dot = Vector3.Dot(forward, toOther)    if dot > 0 thennewBoxes[uid] = box    endendendreturn newBoxesend

到这里之后,有人对我的方法提出了质疑,觉得首先遍历取得附近的物品,这个在物品特别多时还是会耗性能的,我觉得确实有道理,所以贴出来跟大家分享


事实上,对于绝大多数游戏来讲,发现敌人的过程,可能不需要在一帧之内就判断出结果,只要能及时发现即可。因此你可以分成好几帧去做。

我的想法核心思想还是射线算法。但是,可以将算法进行一些改进。

比如:每一帧发射n条射线,n是大于等于1的整数,具体发射多少条,可以根据机器性能来。

然后,根据扇形的角度平均分配每条射线的角度。

下一帧时,将每条射线的角度进行偏移,相当于在扇形区域中进行扫描敌人。由于是n条射线同时扫描,所以每条射线的偏移角度最大是整体角度/n。

我之前实现过的一个行为树的敌人判断节点,就是用的这种算法,实验证明,当扇形角度=90度时,n=2就可以获取很好的效果,而且发现n对性能的影响不是很大。