I made a 2D battle royale game and I made my 2D gun too, but I have a problem with the raycast… Here’s the video:
robloxapp-20220527-0751141.wmv (1.7 MB)
(Sorry for the bad quality video)
And here’s my raycast script:
checkBullet.Size = Vector3.new(0.25, 0.25, (targetPos - part1Pos).Magnitude)
checkBullet.CFrame = CFrame.new(part1Pos, targetPos) * CFrame.new(0, 0, -(targetPos - part1Pos).Magnitude / 2)
local result = workspace:Raycast(part1Pos, checkBullet.CFrame.LookVector * reach.Value, params)
--local result = workspace:Raycast(checkBullet.CFrame * CFrame.new(0, 0, checkBullet.Size.Z / 2).Position, checkBullet.CFrame.LookVector * reach.Value, params) <- Ignore this
newBullet.Size = Vector3.new(0.25, 0.25, (targetPos - part1Pos).Magnitude / 4)
If you want to see the whole script, here’s the script:
local gun = script.Parent
local shot = gun:WaitForChild("Shot")
local timer = gun:WaitForChild("Timer")
local ammo = gun:WaitForChild("Ammo")
local damage = gun:WaitForChild("Damage")
local reach = gun:WaitForChild("Reach")
local gunEvent = gun:WaitForChild("GunEvent")
local wsEvent = gun:WaitForChild("WalkSpeedEvent")
local bullets = workspace:WaitForChild("Bullets")
local rep = game:GetService("ReplicatedStorage")
local bullet = rep:WaitForChild("Bullet")
local equipped = false
local fired = false
local firedTime = 0
local eventTime = 0
local fireRate = 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, part1Pos, targetPos, timer)
shot:Play()
local char = plr.Character
local checkBullet = bullet:Clone()
checkBullet.Name = "CheckBullet"
checkBullet.Transparency = 1
checkBullet.Parent = bullets
local newBullet = bullet:Clone()
newBullet.Name = "NewBullet"
newBullet.Transparency = 0
newBullet.Parent = bullets
local params = RaycastParams.new()
params.FilterDescendantsInstances = {char, bullets}
params.FilterType = Enum.RaycastFilterType.Blacklist
params.IgnoreWater = true
if ammo.Value == 0 then
shot:Pause()
checkBullet:Destroy()
newBullet:Destroy()
end
while ammo.Value > 0 do
task.wait()
ammo.Value -= 1
checkBullet.Size = Vector3.new(0.25, 0.25, (targetPos - part1Pos).Magnitude)
checkBullet.CFrame = CFrame.new(part1Pos, targetPos) * CFrame.new(0, 0, -(targetPos - part1Pos).Magnitude / 2)
local result = workspace:Raycast(part1Pos, checkBullet.CFrame.LookVector * reach.Value, params)
--local result = workspace:Raycast(checkBullet.CFrame * CFrame.new(0, 0, checkBullet.Size.Z / 2).Position, checkBullet.CFrame.LookVector * reach.Value, params) <- Ignore this
newBullet.Size = Vector3.new(0.25, 0.25, (targetPos - part1Pos).Magnitude / 4)
for i = 0, 10, 1 do
local t = i / 10
newBullet.CFrame = CFrame.lookAt(part1Pos, targetPos)
newBullet.Position = lerp(part1Pos, targetPos, t)
task.wait(0.001)
end
if result then
newBullet:Destroy()
checkBullet:Destroy()
local hit = result.Instance
local model = hit:FindFirstAncestorOfClass("Model")
if model then
local humanoid = model:FindFirstChildWhichIsA("Humanoid") or nil
if humanoid then
local pickDamage = math.random(damage.Value, damage.Value + 6)
humanoid:TakeDamage(pickDamage)
end
end
break
else
newBullet:Destroy()
checkBullet:Destroy()
end
if checkBullet.Parent == nil or newBullet.Parent == nil then
newBullet:Destroy()
task.wait(0.1)
checkBullet:Destroy()
break
end
end
end
wsEvent.OnServerEvent:Connect(function(plr, status)
if status == "Slow" then
plr.Character.Humanoid.WalkSpeed = 10
elseif status == "Normal" then
plr.Character.Humanoid.WalkSpeed = 20
end
end)
gunEvent.OnServerEvent:Connect(function(plr, mouseRay, part1Pos, targetPos, timer)
fireRate = timer
local char = plr.Character
local humanoid = char.Humanoid
local pack = script.Parent.Parent
if not char == pack then return end
firedTime = tick()
if equipped == true and countCheck() then
if humanoid.Health > 0 and gun.Parent == char then
eventTime = tick()
task.spawn(fire, plr, mouseRay, part1Pos, targetPos, timer)
end
elseif fired == false then
fired = true
task.wait(fireRate - (firedTime - eventTime))
fired = false
end
end)
And my LocalScript:
local player = game.Players.LocalPlayer
local char = player.Character or script.Parent.Parent
local mouse = player:GetMouse()
local gun = script.Parent
local handle = gun:WaitForChild("Handle")
local part1 = gun:WaitForChild("Part1")
local target = gun:WaitForChild("Target")
local click = gun:WaitForChild("Click")
local reach = gun:WaitForChild("Reach")
local mouseId = gun:WaitForChild("MouseID")
local timer = gun:WaitForChild("Timer")
local gunEvent = gun:WaitForChild("GunEvent")
local wsEvent = gun:WaitForChild("WalkSpeedEvent")
local bullets = workspace:WaitForChild("Bullets")
local rep = game:GetService("ReplicatedStorage")
local bullet = rep:WaitForChild("Bullet")
local run = game:GetService("RunService")
local equipped = false
local aiming = false
local firing = false
gun.Equipped:Connect(function()
equipped = true
end)
gun.Unequipped:Connect(function()
equipped = false
end)
mouse.Button1Down:Connect(function()
if equipped == true then
aiming = true
else
aiming = false
end
end)
mouse.Button1Up:Connect(function()
aiming = false
end)
function advancedPos(vector, snap)
return CFrame.new(
math.floor(vector.X / snap + 0.5) * snap,
math.floor(script.Parent.Parent.HumanoidRootPart.Position.Y / snap + 0.5) * snap,
math.floor(vector.Z / snap + 0.5) * snap
)
end
run.RenderStepped:Connect(function()
if equipped == true then
mouse.Icon = "rbxassetid://" .. mouseId.Value
else
mouse.Icon = "rbxassetid://"
end
if equipped == true and aiming == true then
local mouseRay = mouse.UnitRay
local params = RaycastParams.new()
params.FilterDescendantsInstances = {char, bullets}
params.FilterType = Enum.RaycastFilterType.Blacklist
params.IgnoreWater = true
local result = workspace:Raycast(mouseRay.Origin, mouseRay.Direction * reach.Value, params)
if result then
firing = true
wsEvent:FireServer("Slow")
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("Normal")
part1.Parent = rep
target.Parent = rep
end
else
firing = false
wsEvent:FireServer("Normal")
part1.Parent = rep
target.Parent = rep
end
end)
while task.wait() do
if equipped == true and aiming == true and firing == true then
click:Play()
gunEvent:FireServer(mouse.UnitRay, part1.Position, target.Position, timer.Value)
task.wait(timer.Value)
end
end
Thank you! (and sorry for my bad grammar)