Ive recently created a raycast gun system that works very nicely while the player is stationary or moving in a very linear way, however, when the player moves in a less straight/linear way OR the target is also moving, the raycast fails to detect the target and doesnt cause any damage: the raycasts are created on the client (the scripts are provided below) and the damage is done on the server. Ive tried using unreliable remote events in case the issue was too much information being sent out too quickly but that did not remedy the issue. any and all help is greatly appreciated.
-- client
repeat
wait()
until game:IsLoaded()
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local t = script.Parent
local configurations = t.Configuration
local Rep_Storage = game:WaitForChild("ReplicatedStorage")
local EventsFolder = Rep_Storage:WaitForChild("RemoteEvents")
local Anims = t.Anims
local ammo_UI = t.Ammo
local Shoot_UI = t.ShootGUI
local reload_event = EventsFolder:WaitForChild("ReloadEvent")
local Device = nil
local animsC = {Hold = Anims.Hold,ReloadAnim = Anims.Reload}
local loadedHold = player.Character.Humanoid.Animator:LoadAnimation(animsC.Hold)
local loadedReload = player.Character.Humanoid.Animator:LoadAnimation(animsC.ReloadAnim)
local configs = {
Ammo = configurations.Ammo.Value,
Bullet = configurations.Bullet.Value,
Casting = configurations.Casting.Value,
Damage = configurations.Damage.Value,
HeadShotMultiply = configurations.HeadShotMulti.Value,
Cooldown = configurations.Cooldown.Value,
ObsticalDamage = configurations.ObsticalDamage.Value,
Range = configurations.Range.Value,
Reload = configurations.Reload.Value,
Type = configurations.Type.Value
}
local ammo_folder = player:WaitForChild("AmmoValues")
local Local_gun_Ammo = ammo_folder[configs.Bullet.Name]
local CurrentAmmo = configs.Ammo
local canShoot = false
local ShootEvent = t:WaitForChild("Fire")
local shootingM = false
local uis = game:GetService("UserInputService")
local runservice = game:GetService("RunService")
local lighting = game:GetService("Lighting")
local tweenservice = game:GetService("TweenService")
local debris = game:GetService("Debris")
local db = false
local detailAttachment = t.Handle.DetailAttachment
local reloading = false
local function reload()
if reloading == false and t.Parent == player.Character then
local ValueOfSubtraction
if Local_gun_Ammo.Value >= configs.Ammo then
ValueOfSubtraction = configs.Ammo - CurrentAmmo
else
ValueOfSubtraction = Local_gun_Ammo.Value - CurrentAmmo
end
if ValueOfSubtraction <= 0 then
return
end
print(ValueOfSubtraction)
reload_event:FireServer(ValueOfSubtraction,configs.Bullet.Name)
reloading = true
loadedReload:Play()
t.ReloadSound:Play()
wait(configs.Reload)
CurrentAmmo += ValueOfSubtraction
CurrentAmmo = math.min(CurrentAmmo,configs.Ammo)
reloading = false
end
end
coroutine.wrap(function()
runservice.RenderStepped:Connect(function()
if CurrentAmmo <= 0 and Local_gun_Ammo.Value > 0 then
canShoot = false
reload()
elseif CurrentAmmo >= 1 and t.Parent == player.Character then
canShoot = true
end
end)
end)()
coroutine.wrap(function()
while wait() do
if reloading == false then
ammo_UI.Amnt.Text = ""..CurrentAmmo.."|"..Local_gun_Ammo.Value
elseif reloading == true then
ammo_UI.Amnt.Text = "RELOADING"
end
end
end)()
local function shoot()
if db == false and canShoot == true and CurrentAmmo > 0 then
CurrentAmmo -= 1
db = true
t.Click:FireServer(configs.Type)
local originPos = t.Handle.Origin.CFrame
local direction = (t.Handle.Origin.CFrame.LookVector*configs.Range)
local size1 = Vector3.new(0.5,1,0.5)
local params = RaycastParams.new()
params.FilterDescendantsInstances = {script.Parent,script.Parent.Parent}
params.FilterType = Enum.RaycastFilterType.Blacklist
local raycast = workspace:Blockcast(originPos,size1,direction,params)
if raycast then
script.Parent.EffectHitEVent:FireServer(raycast.Position)
if raycast.Instance.Name == "Crate" then
EventsFolder.CratePunch:FireServer(raycast.Instance,configs.ObsticalDamage)
else
if raycast.Instance.Parent:FindFirstChild("Humanoid") then
if raycast.Instance.Name == "Head" then
ShootEvent:FireServer(raycast.Instance.Parent.Humanoid,raycast.Instance,true)
elseif raycast.Instance.Name ~= "Head" then
ShootEvent:FireServer(raycast.Instance.Parent.Humanoid,raycast.Instance,false)
end
end
end
end
ShootEvent:FireServer()
--
wait(configs.Cooldown)
db = false
end
end
--SHOTGUN SHOOT FUNCTION
local function SpreadShot()
local Origins = t.Handle.OriginsFolder
if db == false and canShoot == true then
CurrentAmmo -= 1
db = true
t.Click:FireServer(configs.Type)
for i,v in pairs(Origins:GetChildren()) do
if v:IsA("Attachment") then
local originPos = v.Position
local direction = (v.CFrame.LookVector *configs.Range)
local params = RaycastParams.new()
params.FilterDescendantsInstances = {script.Parent,script.Parent.Parent}
params.FilterType = Enum.RaycastFilterType.Blacklist
local raycast = workspace:Raycast(originPos,direction,params)
if raycast then
if raycast.Instance.Parent:FindFirstChild("Humanoid") then
if raycast.Instance.Name == "Head" then
ShootEvent:FireServer(raycast.Instance.Parent.Humanoid,raycast.Instance,true)
elseif raycast.Instance.Name ~= "Head" then
ShootEvent:FireServer(raycast.Instance.Parent.Humanoid,raycast.Instance,false)
end
else
if raycast.Instance.Name == "Crate" then
--t.DestroyEvent:FireServer(raycast.Instance)
-- EventsFolder:WaitForChild("CratePunch"):FireServer(raycast.Instance)
end
end
end
ShootEvent:FireServer()
wait(configs.Cooldown)
db = false
end
end
end
end
local function DeviceCheck()
if uis.TouchEnabled and not uis.KeyboardEnabled and not uis.MouseEnabled then
Device = 1
print("MOBLE")
elseif not uis.TouchEnabled and uis.KeyboardEnabled and uis.MouseEnabled then
Device = 2
print("PC")
end
end
t.Equipped:Connect(function()
DeviceCheck()
if Device == 1 then
Shoot_UI.Parent = player.PlayerGui
end
loadedHold:Play()
ammo_UI.Parent = player.PlayerGui
if CurrentAmmo <= 0 then
CurrentAmmo = math.min(Local_gun_Ammo.Value,configs.Ammo)
end
end)
t.Unequipped:Connect(function()
loadedHold:Stop()
Shoot_UI.Parent = t
ammo_UI.Parent = t
shootingM = false
end)
repeat
wait()
until Device
if configs.Type == "Single" then
if Device == 1 then
print("ONE")
Shoot_UI.Shoot.MouseButton1Down:Connect(function()
if t.Parent == player.Character and reloading == false then
shoot()
end
end)
elseif Device == 2 then
print("TWO")
mouse.Button1Down:Connect(function()
if t.Parent == player.Character and reloading == false then
shoot()
end
end)
end
elseif configs.Type == "Automatic" then
if Device == 1 then
Shoot_UI.Shoot.MouseButton1Down:Connect(function()
if t.Parent == player.Character and reloading == false then
shootingM = true
end
end)
Shoot_UI.Shoot.MouseButton1Up:Connect(function()
shootingM = false
end)
elseif Device == 2 then
mouse.Button1Down:Connect(function()
if t.Parent == player.Character and reloading == false then
shootingM = true
end
end)
mouse.Button1Up:Connect(function()
shootingM = false
end)
end
elseif configs.Type == "Shotgun" then
if Device == 1 then
Shoot_UI.Shoot.MouseButton1Down:Connect(function()
if t.Parent == player.Character and reloading == false then
SpreadShot()
end
end)
elseif Device == 2 then
mouse.Button1Down:Connect(function()
if t.Parent == player.Character and reloading == false then
SpreadShot()
end
end)
end
end
coroutine.wrap(function()
runservice.RenderStepped:Connect(function()
if shootingM == true and reloading == false and canShoot == true then
shoot()
else
return
end
end)
end)()
uis.InputBegan:Connect(function(input,_gameProcessed)
if input.KeyCode == Enum.KeyCode.R and _gameProcessed == false then
if CurrentAmmo < configs.Ammo then
reload()
end
end
end)
-- server
local rep_storage = game:GetService("ReplicatedStorage")
local debris = game:GetService("Debris")
local effectsStorage = rep_storage:WaitForChild("Effects")
local effects = {blood = effectsStorage.Blood}
local killsoundEffects = rep_storage.KillSounds:GetChildren()
local t = script.Parent
local configurations = t.Configuration
local configs = {
Ammo = configurations.Ammo.Value,
Bullet = configurations.Bullet.Value,
Casting = configurations.Casting.Value,
Damage = configurations.Damage.Value,
HeadShotMultiply = configurations.HeadShotMulti.Value,
Cooldown = configurations.Cooldown.Value,
ObsticalDamage = configurations.ObsticalDamage.Value,
Range = configurations.Range.Value,
Reload = configurations.Reload.Value,
Type = configurations.Type.Value
}
local tweenservice = game:GetService("TweenService")
local info = TweenInfo.new(
.001,
Enum.EasingStyle.Linear,
Enum.EasingDirection.In,
0,
false,
0
)
local posT
coroutine.wrap(function()
while wait() do
if configs.Type ~= "Shotgun" then
posT = t.Handle.TweenLocation.WorldPosition
end
end
end)()
local function AdjustKillerGUN(plr,humanoid)
local name = humanoid.parent.Name
local shotplayer = nil
for i,v in pairs(game.Players:GetChildren()) do
if v.Name == name then
shotplayer = v
shotplayer.InformationValues.LastPlayer.Value = plr
-- print(""..shotplayer.Name.." was shot by: "..plr.Name)
end
end
end
local function ResetPlayerValues(humanoid)
local PlayerOfReset = nil
for i,v in pairs(game.Players:GetChildren()) do
if v.Name == humanoid.Parent.Name then
PlayerOfReset = v
PlayerOfReset.InformationValues.LastPlayer.Value = nil
end
end
end
script.Parent.Fire.OnServerEvent:Connect(function(plr,humanoid,PartHit,Headshot)
if humanoid then
if humanoid.Health ~= 0 and humanoid.Health > 0 then
if Headshot == true then
AdjustKillerGUN(plr,humanoid)
local clonedBlood = effects.blood:Clone()
clonedBlood.Parent = PartHit
clonedBlood:Emit(50)
debris:AddItem(clonedBlood,1)
humanoid.Health -= script.Parent.Configuration.Damage.Value*script.Parent.Configuration.HeadShotMulti.Value
humanoid.Parent.HumanoidRootPart.BULLETHIT:Play()
if humanoid.Health <= 0 then
local chosenSound = killsoundEffects[math.random(1,#killsoundEffects)]
local clone = chosenSound:Clone()
clone.Parent = script.Parent
clone:Play()
debris:AddItem(clone,10)
plr.Kills.Value +=1
rep_storage.RemoteEvents.Kill:FireClient(plr,humanoid.Parent,script.Parent.Name)
rep_storage.RemoteEvents.KillALL:FireAllClients(plr,humanoid.Parent,script.Parent.Name)
coroutine.wrap(function()
wait(1)
ResetPlayerValues(humanoid)
end)
humanoid.Parent.HumanoidRootPart.Anchored = true
for i,v in pairs(PartHit.Parent:GetDescendants()) do
if v:IsA("BasePart") then
v.CanCollide = false
v.CanQuery = false
v.CanTouch = false
end
end
end
elseif Headshot == false and humanoid then
AdjustKillerGUN(plr,humanoid)
local clonedBlood = effects.blood:Clone()
clonedBlood.Parent = PartHit
clonedBlood:Emit(50)
debris:AddItem(clonedBlood,1)
humanoid.Health -= script.Parent.Configuration.Damage.Value
humanoid.Parent:FindFirstChild("HumanoidRootPart").BULLETHIT:Play()
if humanoid.Health <= 0 then
plr.Kills.Value +=1
local chosenSound = killsoundEffects[math.random(1,#killsoundEffects)]
local clone = chosenSound:Clone()
clone.Parent = script.Parent
clone:Play()
debris:AddItem(clone,10)
rep_storage.RemoteEvents.Kill:FireClient(plr,humanoid.Parent,script.Parent.Name)
rep_storage.RemoteEvents.KillALL:FireAllClients(plr,humanoid.Parent,script.Parent.Name)
humanoid.Parent.HumanoidRootPart.Anchored = true
for i,v in pairs(PartHit.Parent:GetDescendants()) do
if v:IsA("BasePart") then
v.CanCollide = false
v.CanQuery = false
v.CanTouch = false
end
end
end
end
end
end
end)
t.Click.OnServerEvent:Connect(function(plr,typeG)
if typeG == 'Single' or typeG == "Automatic" then
local detailAttachment = t.Handle.DetailAttachment
detailAttachment.ShotFire:Emit(90)
t.Handle.Sound:Play()
local clonedcasting = configs.Casting:Clone()
local bullet = configs.Bullet
clonedcasting.Parent = t
clonedcasting.CFrame = t.Handle.CastingsAttachment.WorldCFrame
t.Handle.TweenLocation.Shoot:Emit(10)
clonedcasting.Velocity = clonedcasting.CFrame.LookVector * 5
debris:AddItem(clonedcasting,1)
coroutine.wrap(function()
detailAttachment.ShotLight.Enabled = true
task.wait(.1)
detailAttachment.ShotLight.Enabled = false
end)()
elseif typeG == "Shotgun" then
local detailAttachment = t.Handle.DetailAttachment
detailAttachment.ShotFire:Emit(90)
t.Handle.Sound:Play()
local clonedcasting = configs.Casting:Clone()
local bullet = configs.Bullet
clonedcasting.Parent = t
clonedcasting.CFrame = t.Handle.CastingsAttachment.WorldCFrame
clonedcasting.Velocity = clonedcasting.CFrame.LookVector * 5
debris:AddItem(clonedcasting,1)
coroutine.wrap(function()
detailAttachment.ShotLight.Enabled = true
task.wait(.1)
detailAttachment.ShotLight.Enabled = false
end)()
for i,v in pairs(t.Handle.OriginsFolder:GetChildren()) do
v.Shoot:Emit(10)
end
end
end)
