What is the issue?
I’m trying to script a door opening and closing when a ProximityPrompt is triggered. The door has no problems opening, but it won’t close and I can’t figure out why.
I think the issue may be lines 30-45 in the ModuleScript (below). I was looking at the developer documentation on proximity prompts and trying to follow the script for the doors in the sample place they linked, but I don’t really understand those lines.
local RunService = game:GetService("RunService")
local ObjectActions = {}
function ObjectActions.promptTriggeredActions(promptObject, player)
-- Gets the Mesh that parents the prompt
local ancestorMesh = promptObject:FindFirstAncestorWhichIsA("MeshPart")
if ancestorMesh.Name == "RDoor" or ancestorMesh.Name == "LDoor" or ancestorMesh.Name == "Tailgate" then
ancestorMesh.Anchored = false
-- Gets the HingeConstraint
local hinge = ancestorMesh:FindFirstChildWhichIsA("HingeConstraint", true)
-- Checks whether state is opened or closed
local Open = ancestorMesh:GetAttribute("Open")
if Open then
hinge.TargetAngle = hinge.LowerAngle
elseif not Open then
hinge.TargetAngle = hinge.UpperAngle
end
hinge.AngularSpeed = 1
-- Disables prompt while opening/closing
promptObject.Enabled = false
-- I don't understand this part much, this may be where the trouble is
local connection
connection = RunService.Stepped:Connect(function(t, dt)
if hinge.TargetAngle > hinge.CurrentAngle and hinge.TargetAngle - hinge.CurrentAngle < 0.05 then
Open = true
hinge.AngularSpeed = 0
promptObject.ActionText = "Close"
promptObject.Enabled = true
connection:Disconnect()
elseif hinge.TargetAngle < hinge.CurrentAngle and hinge.CurrentAngle - hinge.TargetAngle < 0.05 then
Open = false
hinge.AngularSpeed = 0
promptObject.ActionText = "Open"
promptObject.Enabled = true
connection:Disconnect()
end
end)
end
end
function ObjectActions.promptHoldBeganActions(promptObject, player)
end
function ObjectActions.promptHoldEndedActions(promptObject, player)
end
return ObjectActions
Script connecting ProximityPrompt to ObjectActions (PromptEvents):
local ProximityPromptService = game:GetService("ProximityPromptService")
local ServerScriptService = game:GetService("ServerScriptService")
local ObjectActions = require(ServerScriptService.ObjectActions)
-- Detects when prompt is triggered
function onPromptTriggered(promptObject, player)
ObjectActions.promptTriggeredActions(promptObject, player)
end
-- Detects when prompt hold begins
function onPromptHoldBegan(promptObject, player)
ObjectActions.promptHoldBegunActions(promptObject, player)
end
-- Detects when prompt hold ends
function onPromptHoldEnded(promptObject, player)
ObjectActions.promptHoldEndedActions(promptObject, player)
end
-- Connects prompt events to functions
ProximityPromptService.PromptTriggered:Connect(onPromptTriggered)
ProximityPromptService.PromptButtonHoldBegan:Connect(onPromptHoldBegan)
ProximityPromptService.PromptButtonHoldEnded:Connect(onPromptHoldEnded)
Both scripts are in ServerScriptService.
What solutions have you tried so far?
Making hinge.AngularSpeed -1 when closing
Rotating the hinge attachments differently
Messing around with upper/lower limits of hinge
Messing around with ObjectActions
Reading developer documentation and looking at proximity prompt sample place
As I’m new to this stuff I’d also appreciate any feedback if you have any.
I rewrote the ModuleScript a bit to make the part I was having trouble with more simple, but it still doesn’t work.
New ModuleScript:
local RunService = game:GetService("RunService")
local ObjectActions = {}
function ObjectActions.promptTriggeredActions(promptObject, player)
-- Gets the Mesh that parents the prompt
local ancestorMesh = promptObject:FindFirstAncestorWhichIsA("MeshPart")
if ancestorMesh.Name == "RDoor" or ancestorMesh.Name == "LDoor" or ancestorMesh.Name == "Tailgate" then
ancestorMesh.Anchored = false
-- Gets the HingeConstraint
local hinge = ancestorMesh:FindFirstChildWhichIsA("HingeConstraint", true)
-- Checks whether state is opened or closed
local Open = ancestorMesh:GetAttribute("Open")
if Open == true then
hinge.TargetAngle = hinge.LowerAngle
elseif Open == false then
hinge.TargetAngle = hinge.UpperAngle
end
-- Activates hinge servo
hinge.AngularSpeed = 1
-- Disables prompt while opening/closing
promptObject.Enabled = false
local connection
connection = RunService.Stepped:Connect(function(t, dt)
if (hinge.CurrentAngle <= hinge.TargetAngle and hinge.TargetAngle < 0) or (hinge.CurrentAngle >= hinge.TargetAngle and hinge.TargetAngle >= 0) then
-- If closed, set as open
if not Open then
Open = true
hinge.AngularSpeed = 0
promptObject.ActionText = "Close"
promptObject.Enabled = true
connection:Disconnect()
-- If open, set as closed
elseif Open then
Open = false
hinge.AngularSpeed = 0
promptObject.ActionText = "Open"
promptObject.Enabled = true
connection:Disconnect()
end
end
end)
end
end
function ObjectActions.promptHoldBeganActions(promptObject, player)
end
function ObjectActions.promptHoldEndedActions(promptObject, player)
end
return ObjectActions
This never runs, so that means it never senses it as open.
Do you think this could possibly reset it each time it runs? I don’t think it does, as it’s reading the attribute first, not setting it without checking, but I’m out of ideas.
I also tried changing Open = true/false to ancestorMesh:SetAttribute("Open", true/false, but that didn’t fix it.
I made a quick script to check if it actually changes it or not
(I also tried it with a BoolValue instead of an attribute to see if that would change anything)
Looking at print statements I put in the the ModuleScript it looks like it is resetting the value of Open every time it runs, but it’s always loading the attribute as false even when it clearly sets it as true.
See if they work to help you track through the script to see what is failing.
local RunService = game:GetService("RunService")
local ObjectActions = {}
function ObjectActions.promptTriggeredActions(promptObject, player)
Print(“Triggered”)
-- Gets the Mesh that parents the prompt
local ancestorMesh = promptObject:FindFirstAncestorWhichIsA("MeshPart")
if ancestorMesh.Name == "RDoor" or ancestorMesh.Name == "LDoor" or ancestorMesh.Name == "Tailgate" then
Print(“Ancestor Mesh Matches”)
ancestorMesh.Anchored = false
-- Gets the HingeConstraint
local hinge = ancestorMesh:FindFirstChildWhichIsA("HingeConstraint", true)
Print(“hinge = ”, hinge)
-- Checks whether state is opened or closed
local Open = ancestorMesh:GetAttribute("Open")
if Open == true then
Print(“Open attribute is true”)
hinge.TargetAngle = hinge.LowerAngle
elseif Open == false then
Print(“Open attribute is false”)
hinge.TargetAngle = hinge.UpperAngle
end
-- Activates hinge servo
hinge.AngularSpeed = 1
-- Disables prompt while opening/closing
promptObject.Enabled = false
local connection
connection = RunService.Stepped:Connect(function(t, dt)
Print(“RunService”)
if (hinge.CurrentAngle <= hinge.TargetAngle and hinge.TargetAngle < 0) or (hinge.CurrentAngle >= hinge.TargetAngle and hinge.TargetAngle >= 0) then
Print(“Adjusting TargetAngle”)
-- If closed, set as open
if not Open then
Print(“Closed, opening”)
Open = true
hinge.AngularSpeed = 0
promptObject.ActionText = "Close"
promptObject.Enabled = true
connection:Disconnect()
-- If open, set as closed
elseif Open then
Print”(Open, closing)
Open = false
hinge.AngularSpeed = 0
promptObject.ActionText = "Open"
promptObject.Enabled = true
connection:Disconnect()
end
end
end)
end
end
function ObjectActions.promptHoldBeganActions(promptObject, player)
end
function ObjectActions.promptHoldEndedActions(promptObject, player)
end
return ObjectActions