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.
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!
Locked by SteamG00B, fredfishy, and Amiaa16
This question has been locked to preserve its current state and prevent spam and unwanted comments and answers.
Why was this question closed?