Having problems with doors

I just want to make a prompt door that opens correctly to the side you’re facing, but if I rotate the door it completely breaks and either doesn’t open or open too far, the hinge rotation for some reason doesnt correspond with the goal


Door script

local door = script.Parent
local hinge = door:WaitForChild("DoorHinge")
local origin = hinge.Rotation
local originCfr = hinge.CFrame
local ts = game:GetService("TweenService")
local info = TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut)
local opened = false
print(origin)

for _, prompt in pairs(door:GetDescendants()) do
	if prompt:IsA("ProximityPrompt") then
		prompt.Triggered:Connect(function()
			if not opened then
				opened = true
				if prompt.Parent.Name == "OpenFromIn" then
					local goal = {}
					goal.CFrame = hinge.CFrame * CFrame.Angles(0, math.rad(origin.Y - 90), 0)
					print(origin.Y - 90, "-- goal")
					local tween = ts:Create(hinge, info, goal)
					for _, prompt in pairs(door:GetDescendants()) do
						if prompt:IsA("ProximityPrompt") then
							prompt.Enabled = false
						end
					end
					tween:Play()
					tween.Completed:Wait()
					print(hinge.Orientation, "--end orientation")
					for _, prompt in pairs(door:GetDescendants()) do
						if prompt:IsA("ProximityPrompt") then
							prompt.Enabled = true
							prompt.ActionText = "Close"
						end
					end
				elseif prompt.Parent.Name == "OpenFromOut" then
					local goal = {}
					goal.CFrame = hinge.CFrame * CFrame.Angles(0, math.rad(origin.Y + 90), 0)
					print(origin.Y + 90, "-- goal")
					local tween = ts:Create(hinge, info, goal)
					for _, prompt in pairs(door:GetDescendants()) do
						if prompt:IsA("ProximityPrompt") then
							prompt.Enabled = false
						end
					end
					tween:Play()
					tween.Completed:Wait()
					print(hinge.Orientation, "-- end orientation")
					for _, prompt in pairs(door:GetDescendants()) do
						if prompt:IsA("ProximityPrompt") then
							prompt.Enabled = true
							prompt.ActionText = "Close"
						end
					end
				end
			elseif opened then
				opened = false
				local goal = {}
				goal.CFrame = originCfr
				local tween = ts:Create(hinge, info, goal)
				for _, prompt in pairs(door:GetDescendants()) do
					if prompt:IsA("ProximityPrompt") then
						prompt.Enabled = false
					end
				end
				tween:Play()
				tween.Completed:Wait()
				opened = false
				for _, prompt in pairs(door:GetDescendants()) do
					if prompt:IsA("ProximityPrompt") then
						prompt.Enabled = true
						prompt.ActionText = "Open"
					end
				end
			end
		end)
	end
end

this singlehandedly makes me not want to continue this project so help would be appreciated

1 Like

Can you send the door model itself so I can do some testing? I’d love to help but this is one of those issues where I’d just throw things at it until it works.

Please do not quit this project! its look very good so far. Also you need to work on refactoring (Cleaning) your code because i cannot read a single thing, for example your shortening the names of your values eg, “ts” should be something like “tweenService.”

Also, doors only move in one direction but anyway lol.

Steps to improve debugging

  1. Make the code much more easier to read, and update in future.
  2. Find an alternative solution to fix this problem.
  3. Add optimization.

Combing these steps and improvements we get this.

--TODO: REFRACTOR, IMPROVE/OPTIMIZE, FIND SOLUTIONS
--[[

Goal : I just want to make a prompt door that opens correctly to the 
    side you’re facing.

Problem : but if I rotate the door it completely breaks and 
    either doesn’t open or open too far, the hinge rotation for some reason 
    doesnt correspond with the goal.

--]]

--# Services
local TweenService = game:GetService("TweenService")

--# Objects
local door = script.Parent
local doorHinge : BasePart = door:WaitForChild("DoorHinge")

--# Values
local doorOrigin = doorHinge.CFrame
local doorOriginRotation = doorOrigin.Rotation

local doorIsOpened = false

local doorIsDelayed = false

local tweenInfo = TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut)

--# Functions
function tween(instance : Instance, propertyTable : {any}) : Tween
    return TweenService:Create(instance, tweenInfo, propertyTable)
end

function controlDoor(doorPrompt:ProximityPrompt)
    -- OpenFromIn
    -- OpenFromOut

    local function setPrompts(actionText:string, enabled:boolean)
        assert(actionText, "Action text cannot be nil.")

        actionText = tostring(actionText)
        enabled = enabled ~= nil and enabled or true

        for _, foundPrompt : ProximityPrompt in door:GetDescendants() do
            if not foundPrompt:IsA("ProximityPrompt") then -- preventing nesting
               continue
            end

            foundPrompt.Enabled = enabled
            foundPrompt.ActionText = actionText
        end
    end

    local function doorTriggered(activator:Player)
       if doorIsDelayed then
            return
       end

        if doorIsOpened == true then
            doorIsDelayed = true

            doorIsOpened = false

            local goal = {
                CFrame = doorOrigin
            }

            local doorTween = tween(doorHinge, goal)

            setPrompts("", false)

            doorTween:Play()
            doorTween.Completed:Wait()

            setPrompts("Open", true)
        elseif doorIsOpened == false then
            doorIsDelayed = true

            doorIsOpened = true

            local doorPromptPartName = doorPrompt.Parent.Name

            if doorPromptPartName == "OpenFromIn" then
                local goal = {
                    CFrame = doorOrigin * CFrame.Angles(0, math.rad(doorOriginRotation.Y - 90), 0)
                }

                local doorTween = tween(doorHinge, goal)
                setPrompts("", false)

                doorTween:Play()
                doorTween.Completed:Wait()

                setPrompts("Close", true)
            elseif doorPromptPartName == "OpenFromOut" then
                local goal = {
                    CFrame = doorOrigin * CFrame.Angles(0, math.rad(doorOriginRotation.Y + 90), 0)
                }

                local doorTween = tween(doorHinge, goal)
                setPrompts("", false)

                doorTween:Play()
                doorTween.Completed:Wait()

                setPrompts("Close", true)
            end
        end

        doorIsDelayed = false
    end

    doorPrompt.Triggered:Connect(doorTriggered) -- once the prompt is triggered...
end

--# Connections
for _, doorPrompt : ProximityPrompt in pairs(door:GetDescendants()) do -- get all the prompts in the door and controls them to control the rotation of the door..
	if doorPrompt:IsA("ProximityPrompt") then
		controlDoor(doorPrompt)
	end
end

Main Issue
The main issue i detected in your code was this goal.CFrame = hinge.CFrame * ... you were multiplying its current cframe again meaning it could rotate wrongly, we changed this to CFrame = doorOrigin * ...

I hope this code works for you, please respond soon.

1 Like

Another way we could do this in-out rotating is by checking the players position relative to the face of the door (look-vector,) But I’m jut following what you did.

I’ll try this tomorrow, thanks for the help! :smile:

1 Like

heres the door model

I have already made your idea in my studio. But instead of using TweenService. I used HingeConstraint.

Hope this would help you or you can proceed your own way.

Here is the script:

local hinge = script.Parent  -- HingeConstraint
local prox = script.Parent.Parent.ProximityPrompt   -- Reference to ProximityPrompt

local inpart = script.Parent.Parent.Parent.InPart   -- Part to detect at which side of Door is player at.
local outpart = script.Parent.Parent.Parent.OutPart -- Part to detect at which side of Door is player at.

local newangle = nil 

local isopen = false   -- To ensure gate is closed.

inpart.Touched:Connect(function(hit)
	
	local character = hit.Parent
	local humanoid = character:FindFirstChild("Humanoid")
	if humanoid then
		if not isopen then   -- To ensure hinge is closed before setting new angle.
			newangle = 90   
		end
	end
end)

outpart.Touched:Connect(function(hit)

	local character = hit.Parent
	local humanoid = character:FindFirstChild("Humanoid")
	if humanoid then
		if not isopen then    -- To ensure hinge is closed before setting new angle.
			newangle = -90
		end
	end
end)

prox.Triggered:Connect(function()   -- Function to open and close door
	
	if not isopen then
		hinge.TargetAngle = newangle
		script.Parent.Sound:Play()
		isopen = true
	else
		hinge.TargetAngle = 0
		script.Parent.Sound:Play()
		isopen = false
	end
end)
1 Like

This works perfectly! Thanks for the help! :grin:

1 Like

No problem! don’t give up on the game yet!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.