Unity3D_类捕鱼项目,子弹反弹效果实现

36 篇文章 0 订阅
14 篇文章 1 订阅

子弹反弹示意图如下:

1.墙体与子弹均为碰撞体

2.前提条件:需要知道子弹前进方向向量,墙体方向向量

3.计算简易过程,黄色为子弹方向向量,计算出与墙的夹角,根据入射角等于反射角算出橙色方向向量。此时只是子弹方向改变了,接下来还要算出位置的偏移量,根据与墙夹角与子弹本身的大小由三角函数sin/cos算出偏移量,最终效果如红色箭头。

代码:

-- 子弹反弹,ColliderObj:碰撞墙体共4面. 
-- self.bulletObjLength为子弹长度估算值, self.Dir为子弹当前的方向向量, self.o_Transform为子弹实例
function BCAmmoBase:ReflectBullet(ColliderObj)

    -- inNormal: 墙体方向向量,用于计算反射角,为法线
    -- XOrZ: 判断子弹碰撞为水平墙体还是垂直墙体
    -- iden: 子弹所碰撞墙体的标识,用于记录上次碰撞的墙体
    local inNormal, XOrZ, iden = nil
    if tostring(ColliderObj.transform.name) == "ForwardWall" then
        inNormal = Vector3(0, 0, -1)
        XOrZ = true
        iden = "F"
    elseif tostring(ColliderObj.transform.name) == "BackWall" then
        inNormal = Vector3(0, 0, 1)
        XOrZ = true
        iden = "B"
    elseif tostring(ColliderObj.transform.name) == "LeftWall" then
        inNormal = Vector3(1, 0, 0.1)
        XOrZ = false
        iden = "L"
    elseif tostring(ColliderObj.transform.name) == "RightWall" then
        inNormal = Vector3(-1, 0, 0.1)
        XOrZ = false
        iden = "R"
    end

    if inNormal == nil or iden == nil then
        -- log("inNormal == nil or iden == nil ")
        return
    end

    -- 为了避免子弹飞出墙体,同一墙体禁止反弹多次
    if iden == self.collideLastIden then
        -- log("iden == self.collideLastIden ")
        return
    end

    self.collideLastIden = iden
    self.collideInNormal = inNormal
    self.collideXOrZ = XOrZ

    local reflexDir = Vector3.Reflect(self.Dir, self.collideInNormal)
    local dirAngle = 90 - Vector3.Angle(reflexDir, self.collideInNormal)
    local dic = math.sin(math.rad(dirAngle)) * self.bulletObjLength 
    
    -- log(tostring(reflexDir) .. "  反射向量")
    -- log(tostring(dirAngle) .. "  反射向量与位置矫正的夹角")
    -- log(tostring(dic) .. "  位置矫正")

    -- 位置矫正
    local pos = self.o_Transform.position
    if self.collideXOrZ then
        self.o_Transform.position = reflexDir.x >= 0 and pos + Vector3(dic, 0, 0) or pos - Vector3(dic, 0, 0)
    else
        self.o_Transform.position = reflexDir.z >= 0 and pos + Vector3(0, 0, dic) or pos - Vector3(0, 0, dic)
    end

    -- 方向矫正
    local dir = Vector3.Normalize(reflexDir)
    self.Dir = Vector3(dir.x, 0, dir.z) -- Y轴固定为0,避免子弹上仰或者下倾
    self.o_Transform.rotation = Quaternion.FromToRotation(Vector3.forward, self.Dir)
end

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值