Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

DistanceFromCharacter to open/close a door? [unanswered]

local door = script.Parent
local distance = 5


local function isClose()
    for _, player in pairs(game.Players:GetPlayers()) do
        if player.Character ~= nil and player:DistanceFromCharacter(door.Position) <= distance then
            return true
        end
    end

    return false
end


local function Open()
	for i = 1, 70 do 
		door.CFrame = door.CFrame*CFrame.new(0, 0.5, 0)
		wait()
	end
end

local function Close()
	for i = 70, 1 do
		door.CFrame = door.CFrame*CFrame.new(0, 0.5, 0)
		wait()
	end
end

while true do
wait() 
if isClose() then
Open()
else
Close()
end
wait()
end

The purpose is for the door to open/close based on how far away the player is from the door's position.

The door opens, however it does not close, unfortunately.

Help would be > greatly < appreciated.

2 comments

0

Change the second if to elseif, and take off one end

0

Use the :DistanceFromCharacter() of the player object.

3 answers

✓ Accepted answer

Instead of checking the magnitude twice, you only need to check the magnitude once and then use the else statement as an alternative (this also fixes a rare stuttering issue your door will have if the player is exactly 5 studs away from the door). Next, you do not need to open or close the door for each player. So you can move the magnitude checking code to it's own function or use a variable to store the result of the check for the it statement. As far as I know, it is a stuttering issue caused by the door being cframed .5 studs and then -.5 studs.

Here is the function you can use to check the magnitude:

local function isClose()
	for _, player in pairs(game.Players:GetPlayers()) do
		-- You should still check for the character (since the distance without a character is always 0).
		if player.Character ~= nil and DistanceFromCharacter(door.Position) <= distance then
			return true
		end
	end
	
	return false
end

Then your loop would look like this:

while true do
wait() -- Not really necessary to have a wait here (I could be wrong).
if isClose() then
-- Open the door.
else
-- Close the door.
end
wait() -- I would recommend using a longer delay (such as 1 second). There is no reason to check if a player is close enough so many times a second.
end

For the closing function:

local function Close()
	for i = 70, 1 do
		door.CFrame = door.CFrame*CFrame.new(0, -0.5, 0) -- Use a negative for closing the door.
		wait()
	end
end

Edit: The isClose function was changed to use DistanceFromCharacter. **Edit:**Showed a fix for the door not closing.

3 comments

1

I'll change my answer to reflect your new method. I do hope that this also answered your question.

1

Found the problem, your cframing the door by the same increment. When you need to close it, it adds .5 to the door, instead of -.5, I'll update my answer to show this.

0

Even with the fix, the door doesn't close.

Comments explain the code. Should be slightly more optimized, too.

local door = script.Parent
local distance = 5 --max distance to open door
local max = 5 --Height of open position of door
local min = 0 --Height of close position of door
local inc = .5 --how much to increment door height
local plrDist --The distance of the closest player

--Do every frame. Increase the number to reduce lag. Consider making a function or coroutine and spawning the function or resuming the coroutine.
while wait(0) do 
	plrDist = 10--reset distance
 --This loop gets distance to the closest player
	for _, player in pairs(game.Players:GetPlayers()) do
		if  player.Character ~= nil player.Character:FindFirstChild("Torso") ~= nil then
			local currentDist = player:DistanceFromCharacter(door.CFrame)
			if currentDist  < plrDist then
				plrDist = currentDist
			end
		end
	end
	if plrDist <= distance then --determines whether to open or close the door.
		while door.CFrame.Y < max do --opens the door. Consider making this a function
			door.CFrame = door.CFrame+Vector3.new(0, inc, 0)
			wait()
		end
	else
		while  door.CFrame.Y > min do --closes the door. Consider making this a function.
			door.CFrame = door.CFrame-Vector3.new(0, inc, 0)
			wait()
		end
	end
end

3 comments

0

Aside from the few mistakes in the code (door.Cframe, GetDistanceFromCharacter), it doesn't work either. The door goes into the ground and half of it sticks out.

0

Did you change the max and min numbers?

0

No. And my apologies for the last response;

Why not use an ontouched() function,with an invisible brick outside the door?It would be more efficient (I am not looking at your game,so I may be wrong).

This discussion is preserved as it was. New answers, comments, and votes are closed.