Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

DistanceFromCharacter to open/close a door? [unanswered]

Asked by
Hasburo 150
8 years ago
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.

0
Change the second if to elseif, and take off one end ScriptsAhoy 202 — 8y
0
Use the :DistanceFromCharacter() of the player object. GoldenPhysics 474 — 8y

3 answers

Log in to vote
3
Answered by 8 years ago

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.

1
I'll change my answer to reflect your new method. I do hope that this also answered your question. cjcool12345 58 — 8y
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. cjcool12345 58 — 8y
0
Even with the fix, the door doesn't close. Hasburo 150 — 8y
Ad
Log in to vote
1
Answered by 8 years ago

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
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. Hasburo 150 — 8y
0
Did you change the max and min numbers? GoldenPhysics 474 — 8y
0
No. And my apologies for the last response; Hasburo 150 — 8y
Log in to vote
0
Answered by 8 years ago

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

Answer this question