子弹反弹示意图如下:
1.墙体与子弹均为碰撞体
2.前提条件:需要知道子弹前进方向向量,墙体方向向量
3.计算简易过程,黄色为子弹方向向量,计算出与墙的夹角,根据入射角等于反射角算出橙色方向向量。此时只是子弹方向改变了,接下来还要算出位置的偏移量,根据与墙夹角与子弹本身的大小由三角函数sin/cos算出偏移量,最终效果如红色箭头。
代码:
-- 子弹反弹,ColliderObj:碰撞墙体共4面,AmmoLength:子弹长度估算值,备注:self.Dir为子弹当前的方向向量,self.o_Transform为子弹实例,
function AmmoBase:ReflectBullet(ColliderObj, AmmoLength)
local innormal = nil
local wallnormal = nil
local XOrZ = true
if tostring(ColliderObj.transform.name) == "ForwardWall" then
innormal = Vector3(0, 0, -1)
wallnormal = Vector3(1, 0, 0)
XOrZ = true
elseif tostring(ColliderObj.transform.name) == "BackWall" then
innormal = Vector3(0, 0, 1)
wallnormal = Vector3(1, 0, 0)
XOrZ = true
elseif tostring(ColliderObj.transform.name) == "LeftWall" then
innormal = Vector3(1, 0, 0)
wallnormal = Vector3(0, 0, 1)
XOrZ = false
elseif tostring(ColliderObj.transform.name) == "RightWall" then
innormal = Vector3(-1, 0, 0)
wallnormal = Vector3(0, 0, 1)
XOrZ = false
end
if innormal == nil then
return
end
local wallAngle = Vector3.Angle(self.Dir, wallnormal)
local reflexDir = Vector3.Reflect(self.Dir,innormal)
local dirAngle = 180 - Vector3.Angle(self.Dir, reflexDir)
local dic = math.sin(math.rad(dirAngle)) * AmmoLength
-- log(tostring(wallAngle) .. " 与墙夹角")
-- log(tostring(reflexDir) .. " 矫正向量")
-- log(tostring(dirAngle) .. " 反射夹角")
-- log(tostring(dic) .. " 位置矫正")
local pos = self.o_Transform.position
if XOrZ then
if wallAngle > 90 then
self.o_Transform.position = Vector3(pos.x - dic, pos.y, pos.z)
else
self.o_Transform.position = Vector3(pos.x + dic, pos.y, pos.z)
end
else
if wallAngle > 90 then
self.o_Transform.position = Vector3(pos.x, pos.y, pos.z - dic)
else
self.o_Transform.position = Vector3(pos.x, pos.y, pos.z + dic)
end
end
self.Dir = reflexDir
self.o_Transform.rotation = Quaternion.FromToRotation(Vector3.forward, self.Dir) -- 方向矫正
end
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。