Hey developers!
I’ve just finished making my weapon using raycasting, it’s not very good but it’s a start. It has a lot of bugs in it (not shooting where the mouse is if the camera is at a certain angle) and is not how I would imagine games like Arsenal make weapons, does anyone know how I could improve this code to be more efficient, and how big games make weapon systems?
Client:
local player = game.Players.LocalPlayer
local UIS = game:GetService("UserInputService")
local mouse = player:GetMouse()
local playerGui = player:WaitForChild("PlayerGui")
local tool = script.Parent
local runService = game:GetService("RunService")
local camera = workspace.CurrentCamera
local shoot_event = tool:WaitForChild("Shoot")
local reload_event = tool:WaitForChild("Reload")
local player_killed_event = tool:WaitForChild("PlayerKilled")
local hit_player = tool:WaitForChild("HitPlayer")
local hold_anim = tool:WaitForChild("Hold")
local hold_track = player.Character:WaitForChild("Humanoid").Animator:LoadAnimation(hold_anim)
local ammoUI = tool:WaitForChild("AmmoUI")
local player_killedUI = playerGui:WaitForChild("PlayerKilled")
local hitmarkerEffect = ammoUI:WaitForChild("Hitmarker")
local hitmarkerSound = tool:WaitForChild("Hitmarker")
local bullet = game.ReplicatedStorage:WaitForChild("Bullet")
local reloading = false
local maxAmmo = 30
local currentAmmo = maxAmmo
local mouseDown = false
local function textEffect(textLabel, operator)
local method
spawn(function()
for index = 1, 20 do
if operator == "-" then
textLabel.TextTransparency -= 0.05
task.wait(.01)
else
textLabel.TextTransparency += 0.05
task.wait(.01)
end
end
end)
end
local function _rayHitPlayer()
hitmarkerSound:Play()
spawn(function()
hitmarkerEffect.Visible = true
task.wait(.01)
hitmarkerEffect.Visible = false
end)
textEffect()
end
local function castRay(mousePos)
shoot_event:FireServer("nil")
local origin = tool:WaitForChild("ShootPart").Position
local direction = (mousePos - origin).Unit
local rayInfo = RaycastParams.new()
rayInfo.FilterDescendantsInstances = {player.Character, tool}
rayInfo.FilterType = Enum.RaycastFilterType.Blacklist
local result = workspace:Raycast(origin, direction * 500, rayInfo)
local inter = result and result.Position or (direction * 500) - origin
local distanceTravel = (origin - inter).Magnitude
local bulletClone = bullet:Clone()
bulletClone.Size = Vector3.new(0.1, 0.1, distanceTravel)
bulletClone.CFrame = CFrame.new(origin, inter) * CFrame.new(0, 0, -distanceTravel / 2)
bulletClone.Parent = workspace
if result then
local instancePart = result.Instance
if instancePart then
if instancePart.Parent then
if instancePart.Parent:FindFirstChild("Humanoid") or instancePart.Parent.Parent:FindFirstChild("Humanoid") then
local humanoid = instancePart.Parent:FindFirstChild("Humanoid") or instancePart.Parent.Parent:FindFirstChild("Humanoid")
_rayHitPlayer()
if humanoid.Health > 0 then
shoot_event:FireServer(humanoid)
end
end
end
end
end
task.wait(.001)
bulletClone:Destroy()
end
local function fireBullet()
while mouseDown == true do
camera.CFrame = camera.CFrame * CFrame.Angles(math.pi / 100, 0, 0)
currentAmmo -= 1
castRay(mouse.Hit.Position)
wait(0.09)
end
end
mouse.Button1Down:Connect(function()
mouseDown = true
end)
mouse.Button1Up:Connect(function()
mouseDown = false
end)
tool.Equipped:Connect(function()
ammoUI.Parent = player.PlayerGui
hold_track.Looped = true
hold_track:Play()
end)
tool.Unequipped:Connect(function()
ammoUI.Parent = tool
hold_track.Looped = false
hold_track:Stop()
end)
mouse.Button1Down:Connect(function()
if player.Character:FindFirstChild(tool.Name) and reloading == false and currentAmmo > 0 and player.Character.Humanoid.Health > 0 then
camera.CFrame = camera.CFrame * CFrame.Angles(math.pi / 100, 0, 0)
currentAmmo -= 1
castRay(mouse.Hit.Position)
wait(0.09)
fireBullet()
end
end)
player_killed_event.OnClientEvent:Connect(function(playerName)
player_killedUI.Back.PlayerName.Text = playerName
local function playerKillEffect(operator)
textEffect(player_killedUI.Back.PlayerName, operator)
textEffect(player_killedUI.Back.Title, operator)
textEffect(player_killedUI.Back.XP, operator)
end
player_killedUI.Back.Visible = true
playerKillEffect("-")
task.wait(3)
playerKillEffect("+")
player_killedUI.Back.Visible = false
end)
Server:
local tool = script.Parent
local shoot_event = tool:WaitForChild("Shoot")
local reload_event = tool:WaitForChild("Reload")
local player_killed_event = tool:WaitForChild("PlayerKilled")
local hit_player = tool:WaitForChild("HitPlayer")
local shoot_sound = tool:WaitForChild("Handle"):WaitForChild("Fire")
local function shootEffect()
shoot_sound:Play()
spawn(function()
tool.Flash.lite.Enabled = true
tool.Flash.Light.Enabled = true
wait()
tool.Flash.lite.Enabled = false
tool.Flash.Light.Enabled = false
end)
end
shoot_event.OnServerEvent:Connect(function(player, hum)
if hum ~= "nil" then
shootEffect()
if hum.Health <= 30 and hum.Health ~= 0 then
hum:TakeDamage(30)
player_killed_event:FireClient(player, hum.Parent.Name)
elseif hum.Health > 30 then
hum:TakeDamage(30)
hit_player:FireClient(player)
end
else
shootEffect()
end
end)
Thanks for reading!