-
What do you want to achieve? Keep it simple and clear!
I’m trying to make a smooth attack projectile
-
What is the issue?
The server and the client don’t seem to match up, even though it’s firing through a remote event so the client should be seeing whats on the server. There also seems to be a slight delay on the server.
Module Script
local module = {}
local damage = false
local hitlist = {}
local TweenService = game:GetService("TweenService")
local runservice = game:GetService("RunService")
function module.energyAttack(player, mousehit)
local energyattack = game.ReplicatedStorage.EnergyAttack:Clone()
local attachment = Instance.new("Attachment")
local humanoidrootpart = player.Character.HumanoidRootPart
attachment.Parent = energyattack
local linearvelocity = Instance.new("LinearVelocity")
linearvelocity.MaxForce = 100000
linearvelocity.Attachment0 = attachment
linearvelocity.Parent = energyattack
energyattack.Position = humanoidrootpart.Position + humanoidrootpart.CFrame.LookVector * 5
linearvelocity.VectorVelocity = (mousehit - energyattack.Position).Unit * 100
energyattack.Parent = workspace
local tweeninfo = TweenInfo.new()
local goal = {
Size = Vector3.new(10,10,10),
Transparency = 1
}
local params = OverlapParams.new()
params.FilterDescendantsInstances = {
player.Character,
energyattack
}
params.FilterType = Enum.RaycastFilterType.Exclude
runservice.Heartbeat:Connect(function(dt)
local hit = workspace:GetPartsInPart(energyattack, params)
for i,v in pairs(hit) do
if v:IsA("BasePart") then
TweenService:Create(energyattack,tweeninfo,goal):Play()
end
end
end)
game.Debris:AddItem(energyattack,1)
damage = false
end
return module
Server Script
local remote = game.ReplicatedStorage.RemoteEvent
local attackhandler = require(game.ReplicatedStorage.ModuleScript)
remote.OnServerEvent:Connect(function(player, mousehit)
attackhandler.energyAttack(player, mousehit)
end)
Local Script
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character.Humanoid
local uips = game:GetService("UserInputService")
local remote = game.ReplicatedStorage.RemoteEvent
local mouse = player:GetMouse()
uips.InputBegan:Connect(function(input)
if input.KeyCode == Enum.KeyCode.F then
remote:FireServer(mouse.Hit.Position)
end
end)
Heres a video showing it
https://gyazo.com/8525345f48776b298c73e328e691e8e5
I’m not clear of exactly what your problem is, but I can say that:
- There will always be a delay from server-client and client-server, we can’t do anything about it.
I know there is delay from server to client, that isn’t the problem. As in the link video, the projectile stops for a second on the server but not on the client. The clients touched is also firing even if it doesnt touch anything but on the server touch does not fire and the tween does not play. The client and the server aren’t seeing the same thing even though it’s being fired through a remote event so the client should see whats on the server.
The projectile is probably acting wonky because the client is attempting to assert network ownership over it since it’s so close.
If you want to make projectiles that feel smooth, you’re going to have to make them client-sided. I’ve got a guide here.
I was doing some testing and it seems that if you click multiple times the spatial query does not stop, I think this might be causing the lag in the video. How do I make the spatial query stop even though I disconnect it already?
https://gyazo.com/e19c377d776702b84c5fdcbf86168773
Module Script
local module = {}
local damage = false
local tweenservice = game:GetService("TweenService")
local heart
function module.EnergyAttack(player, mousehit, clicks)
local energyattack = game.ReplicatedStorage.EnergyAttack:Clone()
local torso = player.Character.HumanoidRootPart
local linearvelocity = Instance.new("LinearVelocity")
local attachment = Instance.new("Attachment")
attachment.Parent = energyattack
linearvelocity.Attachment0 = attachment
linearvelocity.MaxForce = 100000
linearvelocity.VectorVelocity = (mousehit - torso.Position).Unit * 50
linearvelocity.Parent = energyattack
energyattack.Position = torso.Position + Vector3.new(0,5,0) + torso.CFrame.LookVector * 5
energyattack.Name = energyattack.Name.. " "..clicks
energyattack.Parent = workspace
heart = game:GetService("RunService").Heartbeat:Connect(function(dt)
local params = OverlapParams.new()
params.FilterDescendantsInstances = {player.Character, energyattack}
params.FilterType = Enum.RaycastFilterType.Exclude
local hit = workspace:GetPartsInPart(energyattack, params)
local goal = {
Size = Vector3.new(10,10,10),
Transparency = 1
}
for i,v in pairs(hit) do
print(v, energyattack.Name)
if v:IsA("BasePart") then
attachment:Destroy()
linearvelocity:Destroy()
energyattack.Anchored = true
tweenservice:Create(energyattack,TweenInfo.new(), goal):Play()
end
end
end)
task.wait(1)
energyattack:Destroy()
heart:Disconnect()
end
return module
The lag is because you have a spatial query function connected to HeartBeat, and it’s on the server as well. If it absolutely must be on the server (given that it’s fired from a player, it shouldn’t), you should use raycasts instead. My previous guide on hitboxes covers how to make raycasts, though I believe it needs to be updated.
As for it hitting multiple times, it is because you disconnect the function after a second passes, not after it hits a target. You can self-disconnect a function by declaring it as an empty value and then assigning a function to it.
local heart
heart = game:GetService("RunService").Heartbeat:Connect(function(dt)
if HitThing then
heart:Disconnect()
end
end