What do you want to achieve?
Im trying to make client to server to client replication projectile effects for my game, I’ve made the scripts simpler than what I have, to show the basic idea and problem
What is the issue?
How would I replicate the part if the player didn’t hit anything. Also the part only replicates when it hits something and not when the player fires the projectile so theres a lot of latency. I’ve tried to move the remote fireserver but I had problems with the remote replicating multiple times because it’s a spatial query in a loop.
local module = {}
function module.Projectile(character)
local remote = game.ReplicatedStorage.Events.RemoteEvent
local torso = character.HumanoidRootPart
local projectile = game.ReplicatedStorage.Part:Clone()
local hit = false
local linearvelocity = Instance.new("LinearVelocity")
local linearattachment = Instance.new("Attachment")
linearvelocity.MaxForce = 25000
linearvelocity.Attachment0 = linearattachment
linearvelocity.VectorVelocity = torso.CFrame.LookVector * 50
linearvelocity.Parent = linearattachment
linearattachment.Parent = projectile
projectile.Position = torso.Position + torso.CFrame.LookVector * 5
projectile.Parent = workspace
local overlap = OverlapParams.new()
overlap.FilterDescendantsInstances = {character, projectile}
overlap.FilterType = Enum.RaycastFilterType.Exclude
local heart = game:GetService("RunService").Heartbeat:Connect(function()
local hitbox = workspace:GetPartsInPart(projectile)
for i,v in pairs(hitbox) do
if hit then return end
hit = true
remote:FireServer(v.Position, projectile.Name, torso.Position)
end
end)
task.wait(1)
heart:Disconnect()
end
return module
the local script
local uips = game:GetService("UserInputService")
local module = require(game.ReplicatedStorage.ModuleScript)
local remote = game.ReplicatedStorage.Events.RemoteEvent
local tween = game:GetService("TweenService")
uips.InputBegan:Connect(function(input)
if input.KeyCode == Enum.KeyCode.F then
module.Projectile(character)
end
end)
remote.OnClientEvent:Connect(function(hitposition, attackname, origin)
local attack = game.ReplicatedStorage[attackname]:Clone()
attack.Position = origin
attack.Anchored = true
attack.Parent = workspace
tween:Create(attack, TweenInfo.new(), {Position = hitposition}):Play()
end)
the server script
local remote = game.ReplicatedStorage.Events.RemoteEvent
local players = game:GetService("Players")
remote.OnServerEvent:Connect(function(player, hitposition, attackname, origin)
for i,v in pairs(players:GetPlayers()) do
if v ~= player then
-- different player
remote:FireClient(v, hitposition, attackname, origin)
end
end
end)
Well, I mean, what are you waiting to replicate the projectile for? When the client starts their projectile, just send the information for replicating it to the other clients immediately.
I tried this and it works, but when I have a effect that has a explosion when it hits something I’m not sure how I would replicate that with the spatial query hits
It’s only sending when there’s a hit because the remote is triggered inside a for loop. If the table is empty, the loop doesn’t run, so the remote isn’t fired.
You can’t do much to reduce latency itself, but you can interpolate the projectile’s position by passing along its spawn time and calculating where it should be based on that
I got it working but, when I moved the remote event outside the remote would fire multiple times because it was in a heartbeat function, I just made the players give it a linearvelocity instead of tweening it or calculating it.
here’s the code if anyone wants it. I hope this edifies, God bless.
the module script
local module = {}
function module.Projectile(character)
local remote = game.ReplicatedStorage.Events.RemoteEvent
local torso = character.HumanoidRootPart
local projectile = game.ReplicatedStorage.Part:Clone()
local hit = false
local linearvelocity = Instance.new("LinearVelocity")
local linearattachment = Instance.new("Attachment")
linearvelocity.MaxForce = 25000
linearvelocity.Attachment0 = linearattachment
linearvelocity.VectorVelocity = torso.CFrame.LookVector * 50
linearvelocity.Parent = linearattachment
linearattachment.Parent = projectile
projectile.Position = torso.Position + torso.CFrame.LookVector * 5
projectile.Parent = workspace
local overlap = OverlapParams.new()
overlap.FilterDescendantsInstances = {character, projectile}
overlap.FilterType = Enum.RaycastFilterType.Exclude
remote:FireServer(projectile.Name, torso)
local heart = game:GetService("RunService").Heartbeat:Connect(function()
local hitbox = workspace:GetPartsInPart(projectile)
for i,v in pairs(hitbox) do
if hit then return end
hit = true
projectile:Destroy()
end
end)
task.wait(1)
heart:Disconnect()
end
return module
the local script
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local uips = game:GetService("UserInputService")
local module = require(game.ReplicatedStorage.ModuleScript)
local remote = game.ReplicatedStorage.Events.RemoteEvent
local tween = game:GetService("TweenService")
uips.InputBegan:Connect(function(input)
if input.KeyCode == Enum.KeyCode.F then
module.Projectile(character)
end
end)
remote.OnClientEvent:Connect(function(attackname, origin)
local projectile = game.ReplicatedStorage[attackname]:Clone()
local linearvelocity = Instance.new("LinearVelocity")
local linearattachment = Instance.new("Attachment")
linearvelocity.MaxForce = 25000
linearvelocity.Attachment0 = linearattachment
linearvelocity.VectorVelocity = origin.CFrame.LookVector * 50
linearvelocity.Parent = linearattachment
linearattachment.Parent = projectile
projectile.Position = origin.Position + origin.CFrame.LookVector * 5
projectile.Parent = workspace
projectile.Touched:Connect(function(hit)
projectile:Destroy()
end)
end)
the server script
local remote = game.ReplicatedStorage.Events.RemoteEvent
local players = game:GetService("Players")
remote.OnServerEvent:Connect(function(player, attackname, origin)
for i,v in pairs(players:GetPlayers()) do
if v ~= player then
-- different player
remote:FireClient(v, attackname, origin)
end
end
end)
one more thing, how would I do damage when the spatial query in the module hits something, do I use another remote to fire to the server for damage?
I tried doing this and it works alright where I pass the hitbox if its a player in the module script and in the server script I do damage and return, is this a good way to do this or is there a better way?
module
local heart = game:GetService("RunService").Heartbeat:Connect(function()
local hitbox = workspace:GetPartsInPart(projectile)
for i,v in pairs(hitbox) do
if not v.Parent:FindFirstChild("Humanoid") then return end
if hit then return end
hit = true
projectile:Destroy()
remote:FireServer(projectile.Name, torso, v.Parent)
end
end)
server script
local remote = game.ReplicatedStorage.Events.RemoteEvent
local players = game:GetService("Players")
remote.OnServerEvent:Connect(function(player, attackname, origin, hitplayer)
if hitplayer then
hitplayer.Humanoid:TakeDamage(10)
return
end
for i,v in pairs(players:GetPlayers()) do
if v ~= player then
-- different player
remote:FireClient(v, attackname, origin)
end
end
end)