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.
Can anyone help?
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.
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)
Couldn’t you just weld to it a CanCollide invisible part using a WeldConstraint?
Basically, it’s for a character; so that way only a few players can go near the character.
An invisible part wouldn’t really work if the person moved, so I’m trying to add like an invisible forcefield that pushes people away.
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.
That’s why you’d weld the invisible part to the player’s Torso. If the player moves so does the part!
You can use CFrame.new(Vector3 pos, Vector 3 lookAt) to achieve this.
- To get the direction you want the player to push back, do:
- 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’:
CFrame.new(partPos, Vector3.new(headPos.X, partPos.Y, headPos.Z))
- At the moment you have the pushback direction, however you also need to set how far to pushback. To achieve this, do:
CFrame.new(partPos, Vector3.new(headPos.X, partPos.Y, headPos.Z)) * CFrame.new(0, 0, -distance)
- You now need to convert this CFrame into a Vector3. To do this, simply use the .p component of CFrame. This will look like:
(CFrame.new(partPos, Vector3.new(headPos.X, partPos.Y, headPos.Z)) * CFrame.new(0, 0, amount)).p
- Finally, to make the pushback float slightly upwards, include an additional Y componment:
(CFrame.new(partPos, Vector3.new(headPos.X, partPos.Y, headPos.Z)) * CFrame.new(0, 0, amount)).p + Vector3.new(0, height, 0)
To be placed in a localScript:
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
debounce = true
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.