I made a 2D Battle Royale Game, but I have a problem with my gun.
How do you keep the bullet from going through the wall, so that the Dummy behind the wall doesn’t get damaged?
This is my LocalScript:
local player = game.Players.LocalPlayer
local char = player.Character
local mouse = player:GetMouse()
local run = game:GetService("RunService")
local rep = game:GetService("ReplicatedStorage")
local gun = script.Parent
local part1 = gun:WaitForChild("Part1")
local target = gun:WaitForChild("Target")
local handle = gun:WaitForChild("Handle")
local event = gun:WaitForChild("GunEvent")
local wsEvent = gun:WaitForChild("WalkSpeedEvent")
local click = gun:WaitForChild("Click")
local shot = gun:WaitForChild("Shot")
local beam = part1.Beam
local equipped = false
local firing = false
local aiming = false
local reach = gun.Reach.Value
function advancedPos(pos, snap)
return CFrame.new(
math.floor(pos.X / snap + 0.5) * snap,
math.floor(script.Parent.Parent.HumanoidRootPart.Position.Y / snap + 0.5) * snap,
math.floor(pos.Z / snap + 0.5) * snap
)
end
gun.Equipped:Connect(function()
equipped = true
end)
gun.Unequipped:Connect(function()
equipped = false
end)
mouse.Button1Down:Connect(function()
aiming = true
end)
mouse.Button1Up:Connect(function()
aiming = false
end)
run.RenderStepped:Connect(function()
if equipped == true and aiming == true then
beam.TextureLength = reach / 2
local mouseRay = mouse.UnitRay
local params = RaycastParams.new()
params.FilterDescendantsInstances = {char, workspace.Bullets}
params.FilterType = Enum.RaycastFilterType.Blacklist
params.IgnoreWater = true
local result = workspace:Raycast(mouseRay.Origin, mouseRay.Direction * reach, params)
if result then
firing = true
wsEvent:FireServer("10")
part1.Parent = workspace
target.Parent = workspace
part1.CFrame = handle.CFrame
target.CFrame = advancedPos(result.Position + result.Normal * 1.5, 0.001)
else
firing = false
wsEvent:FireServer("20")
target.Parent = rep
part1.Parent = rep
end
else
firing = false
wsEvent:FireServer("20")
target.Parent = rep
part1.Parent = rep
end
end)
while task.wait() do
if equipped == true and aiming == true and firing == true then
click:Play()
event:FireServer(mouse.UnitRay, target.Position, part1.Position)
task.wait(0.1)
end
end
My Script:
local gun = script.Parent
local handle = gun:WaitForChild("Handle")
local event = gun:WaitForChild("GunEvent")
local wsEvent = gun:WaitForChild("WalkSpeedEvent")
local shot = gun:WaitForChild("Shot")
local rep = game:GetService("ReplicatedStorage")
local ammo = rep:WaitForChild("Ammo")
local bullets = workspace:WaitForChild("Bullets")
local equipped = false
local fired = false
local reach = gun.Reach.Value
local damage = gun.Damage.Value
local currentAmmo = gun.CurrentAmmo.Value
local firedTime = 0
local eventTime = 0
local fireRate = 0.1
local humanoidRP = nil
gun.Equipped:Connect(function()
equipped = true
end)
gun.Unequipped:Connect(function()
equipped = false
end)
function lerp(a, b, t)
return a + (b - a) * t
end
function countCheck()
if firedTime - eventTime >= fireRate or fireRate - (firedTime - eventTime) <= 1 / 60 then
return true
end
end
function fire(plr, mouseRay, targetPos, part1Pos)
local char = plr.Character
local hrp = char:WaitForChild("HumanoidRootPart")
local newAmmo = ammo:Clone()
newAmmo.Transparency = 1
newAmmo.Name = "NewAmmo"
newAmmo.Parent = bullets
local newBullet = ammo:Clone()
newBullet.Name = "NewBullet"
newBullet.Parent = bullets
local params = RaycastParams.new()
params.FilterDescendantsInstances = {char, bullets}
params.FilterType = Enum.RaycastFilterType.Blacklist
params.IgnoreWater = true
local lastPos = targetPos
if currentAmmo == 0 then
newBullet.Parent = rep
newAmmo.Parent = rep
shot.Parent = rep
end
while reach > 0 and currentAmmo > 0 do
task.wait()
currentAmmo -= 1
humanoidRP = hrp
newAmmo.Size = Vector3.new(0.1, 0.1, (targetPos - part1Pos).Magnitude)
newAmmo.CFrame = CFrame.new(part1Pos, targetPos) * CFrame.new(0, 0, -(targetPos - part1Pos).Magnitude / 2)
local result = workspace:Raycast(newAmmo.Position, newAmmo.CFrame.LookVector * reach, params)
newBullet.Size = Vector3.new(0.25, 0.25, (targetPos - part1Pos).Magnitude / 4)
for i = 0, 5, 1 do
local t = i / 5
newBullet.CFrame = CFrame.lookAt(part1Pos, targetPos)
newBullet.Position = lerp(part1Pos, targetPos, t)
task.wait(0.001)
end
if result then
newBullet:Destroy()
task.wait(0.1)
newAmmo:Destroy()
local hit = result.Instance
local model = hit:FindFirstAncestorOfClass("Model")
if model then
local humanoid = model:FindFirstChildWhichIsA("Humanoid") or nil
if humanoid then
humanoid:TakeDamage(damage)
end
end
break
else
newBullet:Destroy()
task.wait(0.1)
newAmmo:Destroy()
end
if newAmmo.Parent == nil then
newBullet:Destroy()
task.wait(0.1)
newAmmo:Destroy()
break
end
end
end
event.OnServerEvent:Connect(function(plr, mousePos, targetPos, part1Pos)
local char = plr.Character
local pack = script.Parent.Parent
if not char == pack then return end
firedTime = tick()
if equipped == true and countCheck() then
eventTime = tick()
task.spawn(fire, plr, mousePos, targetPos, part1Pos)
shot:Play()
elseif fired == false then
fired = true
task.wait(fireRate - (firedTime - eventTime))
fired = false
end
end)
wsEvent.OnServerEvent:Connect(function(plr, status)
if status == "10" then
plr.Character.Humanoid.WalkSpeed = 10
elseif status == "20" then
plr.Character.Humanoid.WalkSpeed = 20
end
end)
Thank you! (This is my first topic)