Somebody recently asked a question about how you could push a character away from a part when the character touches the part. I wrote a detailed answer, but the question was deleted, so I'll post the answer as an answer to my own question instead, in case anybody has the same question.
How do I push a character away from a part? (Repost, self-answered)
1 answer
Let's assume that we have a BasePart named "Part", which is the part that will push Players' characters away.
local part = workspace.Part
We'll need to connect a function to BasePart.Touched, an RBXScriptSignal that fires whenever a BasePart touches the BasePart, with the other BasePart passed as the only argument.
local part = workspace.Part
part.Touched:Connect(function(other_part)
end)
When part is touched, let's first check if other_part belongs to a character or not with Players:GetPlayerFromCharacter. If not, we'll return from the function. If so, we'll continue and keep the character for later.
local players = game:GetService("Players")
local part = workspace.Part
part.Touched:Connect(function(other_part)
-- Check if other_part doesn't belong to a character.
local character = other_part.Parent
if not players:GetPlayerFromCharacter(character) then
return
end
end)
Then, we'll check if the character has a Humanoid or not with Instance:FindFirstChild. If not, we'll return from the function. If so, we'll continue and keep the Humanoid for later.
local players = game:GetService("Players")
local part = workspace.Part
part.Touched:Connect(function(other_part)
-- Check if other_part doesn't belong to a character.
local character = other_part.Parent
if not players:GetPlayerFromCharacter(character) then
return
end
-- Check if character has no Humanoid.
local humanoid = character:FindFirstChild("Humanoid")
if not humanoid then
return
end
end)
Now that we've done the necessary gets and checks, we can push the character away from part. First, we'll sit the Humanoid with Humanoid.Sit = true, otherwise the character won't always be pushed. After that, we'll instantiate CFrame at part.Position facing towards other_part.Position. Think of the CFrame as an arrow pointing away from part and towards other_part. This arrow is the direction that we want the character to be pushed, away from part. To get the Vector3 that describes the direction this arrow is pointing, we can use CFrame.LookVector. Now that we have the desired direction, we'll instantiate BodyForce and assign its BodyForce.Force to the direction multiplied by a multiplier (let's go with 5000). Finally, let's assign its parent to other_part.
local players = game:GetService("Players")
local part = workspace.Part
part.Touched:Connect(function(other_part)
-- Check if other_part doesn't belong to a character.
local character = other_part.Parent
if not players:GetPlayerFromCharacter(character) then
return
end
-- Check if character has no Humanoid.
local humanoid = character:FindFirstChild("Humanoid")
if not humanoid then
return
end
-- Push other_part away from part.
humanoid.Sit = true
local direction = CFrame.new(part.Position, other_part.Position).LookVector
local body_force = Instance.new("BodyForce")
body_force.Force = direction * 5000
body_force.Parent = other_part
end)
This works fine, except body_force stays there permanently. Let's Instance:Destroy it after 0.5 seconds.
local players = game:GetService("Players")
local part = workspace.Part
part.Touched:Connect(function(other_part)
-- Check if other_part doesn't belong to a character.
local character = other_part.Parent
if not players:GetPlayerFromCharacter(character) then
return
end
-- Check if character has no Humanoid.
local humanoid = character:FindFirstChild("Humanoid")
if not humanoid then
return
end
-- Push other_part away from part.
humanoid.Sit = true
local direction = CFrame.new(part.Position, other_part.Position).LookVector
local body_force = Instance.new("BodyForce")
body_force.Force = direction * 5000
body_force.Parent = other_part
wait(0.5)
body_force:Destroy()
end)
Finally, we should only have one BodyForce per character. Let's create a dictionary with character as keys and true or nil as values (describing whether or not the character has a BodyForce). We'll check and update this appropriately.
local players = game:GetService("Players")
local part = workspace.Part
local character_body_forces = {}
part.Touched:Connect(function(other_part)
-- Check if other_part doesn't belong to a character.
local character = other_part.Parent
if not players:GetPlayerFromCharacter(character) then
return
end
-- Check if character already has a BodyForce. If not, update.
if character_body_forces[character] then
return
end
character_body_forces[character] = true
-- Check if character has no Humanoid.
local humanoid = character:FindFirstChild("Humanoid")
if not humanoid then
return
end
-- Push other_part away from part.
humanoid.Sit = true
local direction = CFrame.new(part.Position, other_part.Position).LookVector
local body_force = Instance.new("BodyForce")
body_force.Force = direction * 5000
body_force.Parent = other_part
wait(0.5)
body_force:Destroy()
character_body_forces[character] = nil
end)
I hope this helped!
1 comment
I am sure that this will help quite a lot of people because it is an excessive explanation :)
This discussion is preserved as it was. New answers, comments, and votes are closed.

2 comments
I remember that, I was wondering where that question went.
ja