So I’m trying to make a hitbox system that does the following:
Client fires RemoteEvent to the server, giving the server the current time according to the client.
The server every HeartBeat records the time, and the CFrame of the HumanoidRootPart, according to the server.
When the server receives the RemoteEvent, it finds the the time closest to the Time given by client. And creates a Hitbox at the point.
This is the code:
local Players = game:GetService("Players")
local Shared = require(script.Shared)
Players.PlayerAdded:Connect(function(Player)
Player.CharacterAdded:Wait()
Player.Character.Archivable = true
for _,v in pairs(Player.Character:GetDescendants()) do
Player.Character:WaitForChild("HumanoidRootPart")
if v:IsA("BasePart") then
v.CollisionGroup = "Players"
end
end
end)
Players.PlayerRemoving:Connect(function(Player)
if Shared.Past[Player] then
Shared.Past[Player] = nil
end
end)
game.ReplicatedStorage.Hitbox.OnServerEvent:Connect(function(Player, timestamp)
local Character = Player.Character
local HitPart = Instance.new("Part")
HitPart.Size = Vector3.new(1,1,1)
HitPart.Anchored = true
HitPart.CFrame = Character.HumanoidRootPart.CFrame
HitPart.Color = Color3.fromRGB(255,255,0)
HitPart.Transparency = 0
HitPart.CanCollide = false
HitPart.Material = Enum.Material.Neon
HitPart.Parent = workspace
if not Shared.Past[Player] then return end
local CurrentTimestamp = nil
for t, CF in Shared.Past[Player] do
if not CurrentTimestamp then
CurrentTimestamp = t
else
if math.abs(t - timestamp) < math.abs(CurrentTimestamp - timestamp) then
CurrentTimestamp = t
end
end
end
warn(math.abs(workspace:GetServerTimeNow() - timestamp))
warn(math.abs(CurrentTimestamp - timestamp))
local CF = Shared.Past[Player][CurrentTimestamp]
local HitPart = Instance.new("Part")
HitPart.Size = Vector3.new(1,1,1)
HitPart.Anchored = true
HitPart.CFrame = CF
HitPart.Color = Color3.fromRGB(255,0,0)
HitPart.Transparency = 0
HitPart.CanCollide = false
HitPart.Material = Enum.Material.Neon
HitPart.Parent = workspace
end)
game:GetService("RunService").Heartbeat:Connect(function()
for _,Player : Player in Players:GetChildren() do
local Character = Player.Character
if not Character then continue end --//-- passes to next iteration if character is nil
local HumanoidRootPart = Character:FindFirstChild("HumanoidRootPart")
if not HumanoidRootPart then continue end --//-- passes to next iteration if HumanoidRootPart is nil
local t = workspace:GetServerTimeNow()
if Shared.Past[Player] then
Shared.Past[Player][t] = HumanoidRootPart.CFrame
else
Shared.Past[Player] = {}
Shared.Past[Player][t] = HumanoidRootPart.CFrame
end
for t, CF in Shared.Past[Player] do
if workspace:GetServerTimeNow() - t > 0.15 then
Shared.Past[Player][t] = nil
end
end
end
end)
Client:
local UserInputService = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Character = script.Parent
UserInputService.InputBegan:Connect(function(Input, GPE)
if GPE then return end
if Input.UserInputType == Enum.UserInputType.MouseButton1 then
local HitPart = Instance.new("Part")
HitPart.Size = Vector3.new(1,1,1)
HitPart.Anchored = true
HitPart.CFrame = Character.HumanoidRootPart.CFrame
HitPart.Color = Color3.fromRGB(0,255,0)
HitPart.CanCollide = false
HitPart.Transparency = 0
HitPart.Material = Enum.Material.Neon
HitPart.Parent = workspace
ReplicatedStorage.Hitbox:FireServer(workspace:GetServerTimeNow())
end
end)
Problem is the hitbox is being created way too late, much after the client.
Here’s a representation of what I mean:
The Green is the client, yellow is the server, and the little red behind the yellow is where he hitbox will be created with the system.
As you can clearly see the Hitbox according to this will be created even later than the server.
If you have knowledge in this field, please do help me out. Espeically on how I could improve or change this system to make it work or make a good reliable hitbox system.