您的位置:首页 > 移动开发 > Unity3D

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

2017-09-21 10:54 302 查看
有关这个问题,大致提两种思路,其实原理也都类似

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

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

function GetInSightBoxes(hero)
local newBoxes = {}
local pos = hero:GetPosition()
local cameraController = hero.cameraController
local lookForward = cameraController.cameraTrans.forward
for uid, box in pairs(Boxes) do
local 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
end

end
end
return newBoxes
end


2、使用点乘 ,和上面类似,范围值是(-1,1)
-- 得到角色附近 面前的物品
function GetInSightBoxes(hero)
local newBoxes = {}
local pos = hero:GetPosition()
local cameraController = hero.cameraController
local forward = cameraController.cameraTrans:TransformDirection(Vector3.forward)
for uid, box in pairs(Boxes) do
local 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 then
newBoxes[uid] = box
end
end
end
return newBoxes
end

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

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

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

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

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

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

我之前实现过的一个行为树的敌人判断节点,就是用的这种算法,实验证明,当扇形角度=90度时,n=2就可以获取很好的效果,而且发现n对性能的影响不是很大。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息