当前位置:网站首页>Unity3D_ Class fishing project, bullet rebound effect is achieved

Unity3D_ Class fishing project, bullet rebound effect is achieved

2022-07-07 15:52:00 Le_ Sam

The bullet rebound diagram is as follows :

1. Both the wall and the bullet are collision bodies

2. Prerequisite : You need to know the direction vector of the bullet , Wall direction vector

3. Simple calculation process , Yellow is the bullet direction vector , Calculate the included angle with the wall , Calculate the orange direction vector according to the incident angle equal to the reflection angle . At this time, only the direction of the bullet changed , Next, calculate the offset of the position , According to the angle with the wall and the size of the bullet itself, the trigonometric function sin/cos Calculate the offset , The final effect is like the red arrow .

Code :

--  The bullet bounced ,ColliderObj: Collision wall total 4 Noodles . 
-- self.bulletObjLength Estimate the bullet length , self.Dir Is the current direction vector of the bullet , self.o_Transform For example bullets 
function BCAmmoBase:ReflectBullet(ColliderObj)

    -- inNormal:  Wall direction vector , Used to calculate the reflection angle , Is the normal 
    -- XOrZ:  Determine whether the bullet hit the horizontal wall or the vertical wall 
    -- iden:  The sign of the wall where the bullet hit , Used to record the wall of the last collision 
    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

    --  To avoid bullets flying out of the wall , It is forbidden to bounce multiple times on the same wall 
    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) .. "   Reflection vector ")
    -- log(tostring(dirAngle) .. "   The angle between the reflection vector and the position correction ")
    -- log(tostring(dic) .. "   Position correction ")

    --  Position correction 
    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

    --  Direction correction 
    local dir = Vector3.Normalize(reflexDir)
    self.Dir = Vector3(dir.x, 0, dir.z) -- Y The shaft is fixed to 0, Avoid tilting bullets up or down 
    self.o_Transform.rotation = Quaternion.FromToRotation(Vector3.forward, self.Dir)
end

 

原网站

版权声明
本文为[Le_ Sam]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202130609271039.html