I’m trying to make a script that stops people from going too close to a part.
I’ve got code that can insert a BodyPosition into a torso when they get too close; but I can’t figure out how to get it to push the player in the right direction, away from the part.
The direction vector from position A to position B can easily be obtained from posB - posA. You’d need to use a BodyForce with this instead of a BodyPosition.
I’m testing BodyForces by putting them in the UpperTorso of the character and nothing happens.
I’ve been messing with the values but nothing appears to happen.
I’d try putting them in HumanoidRootPart, that works with both R6 and R15 for one. If the force appears to do nothing, try using :GetMass() * constant and keep raising the constant till it has an effect. (GetMass works on a part, for the best results you sum the mass of all parts in the character)
Technically I think you could do an invisible part with collision groups and it would work. However, the invisible part would probably be very likely to fling people because of lag mixed with physics. I like TaaRts idea and I think it would be cool to mix with a magnitude checker. The shorter the magnitude between the player and the part, the higher the constant that pushes the player away.
Pay mind that anything you do to a humanoid is going to be a mess. If you need to move the character using physics, I’d suggest putting the humanoid in “physics mode”. This will prevent the user from controlling the character for a period of time, but… it is likely necessary.
To get the direction you want the player to push back, do:
CFrame.new(partPos, headPos)
In this situation you don’t want to affect the Y coordinate. This can be fixed by setting the Y coordinate of the ‘Head’ to the Y coordinate of the ‘Part’:
local radius = 12
local pushbackDistance = 20
local pushbackHeight = 10
local part = workspace:WaitForChild("Part")
local player = game.Players.LocalPlayer
local debounce = true
while wait(0.1) do
local partPos = part.Position
local currentRadius = player:DistanceFromCharacter(part.Position)
if debounce and radius > 0 and currentRadius <= radius then
if player.Character then
local head = player.Character:FindFirstChild("Head")
if head then
local headPos = head.Position
debounce = false
local bp = Instance.new("BodyPosition")
bp.D = 50
bp.Position = (CFrame.new(partPos, Vector3.new(headPos.X, partPos.Y, headPos.Z)) * CFrame.new(0,0,-pushbackDistance)).p + Vector3.new(0,pushbackHeight,0)
bp.Parent = head
wait(0.5)
bp:Destroy()
debounce = true
end
end
end
end
This is exactly what I was about to post. That’s what I do for enemies that need to stay at range of a player. Good work. I generally just preserve the orientation on the Y axis instead of the whole CFrame as some results can be weird due to the part looking upward to meet the look at point.
With the current answers given, please make sure to post an update if one of them addresses your problem (mark that reply as the solution in that case), or explain why your problem isn’t solved yet.