Give me a step by step guide on how to make hitboxes
You make a box, slightly larger that the object you are trying to detect, and depending on whether the item is anchored or not, you will anchor the hitbox, and if the item isn’t anchored, hitbox will be welded to the item. The hitbox needs to be named “Hitbox”, or something similar, and when an object touches a part named “Hitbox”, do what you need to do.
you could try to use workspace:GetPartsInPart(), it’s a method you can use to
detect any parts inside of a part.
If you want to create a hitbox for each player in the game that detects players inside of the hitbox, this could be a simple example:
local function createHitBox (playerRootPart) -- The HumanoidRootPart of the player
local part = Instance.new("Part") -- Create the hitbox
part.Size = Vector3.new(5,5,5)
part.Transparency = 0.5
part.CanCollide = false
part.Position = playerRootPart.Position
local weld = Instance.new("WeldConstraint") -- Create a weld between the player and the hitbox
weld.Part0 = playerRootPart
weld.Part1 = part
weld.Parent = part
part.Parent = workspace
return part -- return the hitbox so we can store it for use it later
end
local function detectPlayersInHitBox(hitboxOwner,hitBox) -- function to detect the players inside of our hitbox
local players = {} -- this will be our table for the players that are inside of the hitbox
local lastPlayers = {} -- this table will check if a player leave the hitbox, so we can remove it from the players table
game:GetService("RunService").Heartbeat:Connect(function() -- get tha players inside of the hitbox every frame
local partInParts = workspace:GetPartsInPart(hitBox) -- get the current parts in our part
for _,part in ipairs(partInParts) do
local player = part.Parent and game:GetService("Players"):GetPlayerFromCharacter(part.Parent) -- check if the parent of the parts contains and character and directly get the player from that
if player and not (player == hitboxOwner) and not players[player] then -- check if the player exist
lastPlayers[player] = 0 -- set the player in the current players table too
players[player] = 0 -- set the player in the our players table
end
end
for lastPlayer,_ in pairs(players) do -- remove the players that were inside the hitbox but left
if not lastPlayers[lastPlayer] then
players[lastPlayer] = nil
end
end
table.clear(lastPlayers) -- clean up the current players in the hitbox
print(players)
end)
-------- do whatever u want to do with the players that are inside of the players table
end
game.Players.PlayerAdded:Connect(function(player)
local character = player.Character or player.CharacterAdded:Wait() -- Get the player character
local humanoidRootPart = character:FindFirstChild("HumanoidRootPart") -- Get the HumanoidRootPart
local hitBox = createHitBox(humanoidRootPart)
detectPlayersInHitBox(player,hitBox)
end)
Thanks for the script! I’ll test it out
Hey, how can u use this on sever events and user input services and body velocities
could you give me an example? so i can do it on code
Say if it was a fighting or battlegrounds game and what if the player blocks
I did some modifications so we can clean up the last hitbox of the player.
This scripts pushes the players inside of the hitbox of a player when the key “E” is pressed.
this is the server side of the script:
local hitBoxes = {} -- here we will store the players hitBoxes
local pushPlayersEvent = Instance.new("RemoteEvent",game:GetService("ReplicatedStorage"))
pushPlayersEvent.Name = "PushPlayers"
local function createHitBox (playerRootPart) -- The HumanoidRootPart of the player
local part = Instance.new("Part") -- Create the hitbox
part.Size = Vector3.new(5,5,5)
part.Transparency = 0.5
part.CanCollide = false
part.Position = playerRootPart.Position
local weld = Instance.new("WeldConstraint") -- Create a weld between the player and the hitbox
weld.Part0 = playerRootPart
weld.Part1 = part
weld.Parent = part
part.Parent = playerRootPart
return part -- return the hitbox so we can store it for use it later
end
local function detectPlayersInHitBox(hitboxOwner,hitBox) -- function to detect the players inside of our hitbox
local players = {} -- this will be our table for the players that are inside of the hitbox
local lastPlayers = {} -- this table will check if a player leave the hitbox, so we can remove it from the players table
local hbConnection = game:GetService("RunService").Heartbeat:Connect(function() -- get tha players inside of the hitbox every frame
local partInParts = workspace:GetPartsInPart(hitBox) -- get the current parts in our part
for _,part in ipairs(partInParts) do
local player = part.Parent and game:GetService("Players"):GetPlayerFromCharacter(part.Parent) -- check if the parent of the parts contains and character and directly get the player from that
if player and not (player == hitboxOwner) and not players[player] then -- check if the player exist
lastPlayers[player] = 0 -- set the player in the current players table too
players[player] = 0 -- set the player in the our players table
end
end
for lastPlayer,_ in pairs(players) do -- remove the players that were inside the hitbox but left
if not lastPlayers[lastPlayer] then
players[lastPlayer] = nil
end
end
table.clear(lastPlayers) -- clean up the current players in the hitbox
end)
return {
Players = players,
CurrentConnection = hbConnection -- saving the current heartBeat connection so we can disconnect it when the player spawns again for optimizing memory
}
-------- do whatever u want to do with the players that are inside of the players table
end
game.Players.PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function(character) -- Create a new hitbox when a player spawn
if hitBoxes[player] then -- if there is a last hitbox we will disconnect it
hitBoxes[player].CurrentConnection:Disconnect()
end
local humanoidRootPart = character:FindFirstChild("HumanoidRootPart") -- Get the HumanoidRootPart
local hitBox = createHitBox(humanoidRootPart)
local hitBoxInfo = detectPlayersInHitBox(player,hitBox)
hitBoxes[player] = hitBoxInfo
end)
end)
pushPlayersEvent.OnServerEvent:Connect(function(player) -- handle the event that pushes players inside of the hitbox of a player
print(hitBoxes[player])
if not hitBoxes[player] then return end
local playerCharacter = player.Character
local playerHumanoid = playerCharacter and playerCharacter:FindFirstChild("Humanoid")
local playerHumanoidRootPart = playerHumanoid and playerCharacter:FindFirstChild("HumanoidRootPart")
if not playerHumanoidRootPart then return end -- do nothing if doesn't exist
local players = hitBoxes[player].Players -- getting the players inside of the player hitbox
for currentPlayer,_ in pairs(players) do -- push each player inside of the player's hitbox
local char = currentPlayer.Character
local humanoid = char and char:FindFirstChild("Humanoid") -- get the character humanoid if character exist
if humanoid.Health > 0 and playerHumanoid.Health > 0 then -- push the player only if both players health > 0
print("Pushing")
local pushDirection = playerHumanoidRootPart.CFrame.LookVector -- pushing the player against of the pusher direction
local factor = 11200 -- value to increase the push force
local push = pushDirection * factor
pushPlayersEvent:FireClient(currentPlayer,push) -- send a signal to the pushed player so it's own client pushes him
end
end
end)
this is the client side:
local uis = game:GetService("UserInputService")
local pushPlayersEvent = game:GetService("ReplicatedStorage"):WaitForChild("PushPlayers") -- wait for the event
uis.InputBegan:Connect(function(input,_)
if input.KeyCode == Enum.KeyCode.E then -- If player press the key "E" then we are going to send a signal to the server to push the players inside a hitbox
pushPlayersEvent:FireServer()
end
end)
pushPlayersEvent.OnClientEvent:Connect(function(pushDirection) -- event to push the local client when someone pushes a client
local localPlayer = game:GetService("Players").LocalPlayer
local character = localPlayer.Character
local humanoidRootPart = character and character:FindFirstChild("HumanoidRootPart")
if humanoidRootPart then
humanoidRootPart:ApplyImpulse(pushDirection)
end
end)
today you should use ApplyImpulse or change the AssemblyLinearVelocity of a part instead of body velocities because they are deprecated btw
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.