How to stop people from going too close to a part?

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?

Many Thanks.
Elliott :slight_smile:

3 Likes

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.

1 Like

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)

1 Like

Couldn’t you just weld to it a CanCollide invisible part using a WeldConstraint?

2 Likes

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.

6 Likes

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.

  1. To get the direction you want the player to push back, do:

CFrame.new(partPos, headPos)

  1. 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))

  1. 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)

  1. 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

  1. 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)


Example

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
				wait(0.5)
				bp:Destroy()
				debounce = true
			end
		end
	end
end
5 Likes

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.

1 Like

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.

2 Likes