The bullet rebound diagram is as follows:
1. Both walls and bullets are collisions.
2. Prerequisites: We need to know the bullet's forward direction vector and the wall's direction vector.
3. Calculate the simple process. Yellow is the bullet direction vector. Calculate the angle between the bullet and the wall. Calculate the orange direction vector according to the incident angle equal to the reflection angle. At this time, only the bullet direction has changed, and then the offset of position is calculated. According to the angle between the wall and the bullet itself, the offset is calculated by the trigonometric function sin/cos. The final effect is like the red arrow.
Code:
-- The bullet bounced back. ColliderObj: Collision wall has four sides. AmmoLength: Estimated bullet length,Remarks: self.Dir For the current direction vector of the bullet,self.o_Transform An example of a bullet, 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) .. " Angle with wall") -- log(tostring(reflexDir) .. " Correction vector") -- log(tostring(dirAngle) .. " Reflection angle") -- log(tostring(dic) .. " Position correction") 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) -- Direction correction end