apologies for horrific grammar in title, they only allow 100 characters in it
I have a door (one part, united together) and I have it clickable to open. I felt like doors with hinges were too hard to open by pushing at times, especially on mobile, so I thought a better, efficient way to do so is make it clickable. I wrote a script to change the position and rotation so it'll be function able. However, since I'm new to scripting, several errors occurred when making this.
First of all, when clicked, the door goes on top of the nearest solid brick, let's say a roof, and stays there. I tried to make the 'CanCollide = false' when clicked (of course swapped back to true when it automatically closes), but it still goes on top of the roof, or a player when he/she is standing beside it. I feel like it's Roblox's funky way of putting objects on top of one another, and I know it's possible since ZolarKeth and Gusmanak were able to implement it in 'Urbis'.
Also, I feel like the door should have the ability to close by choice, instead of closing automatically. However, all I know how to do is make it automatic, which makes the game feel more "mechanic".
Here's the code;
local Door = script.Parent function onClicked(playerWhoClicked) --opened Door.Position = Vector3.new(34.6, 12.3, 105.1) Door.Rotation = Vector3.new(0, -90, 0) wait(2) --closed Door.Position = Vector3.new(32.1, 12.3, 103.4) Door.Rotation = Vector3.new(0, 0, 0) end Door.ClickDetector.MouseClick:connect(onClicked)
Use CFrame to change the position of the door and angle. To make it less "mechanic", use magnitude.
To change the position it's like changing the position except you change the CFrame. With CFrame.new(). You can change the angles by using CFrame.Angles(). Here is an example.
while wait() do script.Parent.CFrame = CFrame.new(script.Parent.Position.X,script.Parent.Position.Y+1,script.Parent.Position.Z) * CFrame.Angles(0, math.rad(1), 0) --Notice the "*' symbol and the math.rad. Also, notice how this is all on one line. end
Use magnitude to find the distance from part1 to part2.
local magnitude = (part1.Position - part2.Position).magnitude print(magnitude)
Now we add this together.
local Door = script.Parent local openDistance = 15 --Must be 15 studs away local used = false function onClicked(playerWhoClicked) local hrp = playerWhoClicked:FindFirstChild("HumanoidRootPart") local dist = playerWhoClicked:DistanceFromCharacter(Door.Position) if hrp and dist < openDistance and not used then used = true Door.CFrame = CFrame.new(34.6, 12.3, 105.1)*CFrame.Angles(0,math.rad(-90),0) elseif hrp and dist > openDistance and used then used = false Door.CFrame = CFrame.new(32.1, 12.3, 103.4)*CFrame.Angles(0,math.rad(0),0) end print(dist) end Door.ClickDetector.MouseClick:connect(onClicked)
NOTE! THIS SCRIPT DOESN'T WORK!, I DON'T KNOW HOW TO MAKE IT WORK SINCE IT HAS NO ERRORS. THIS I GUESS IS JUST AN EXAMPLE YOU CAN WORK OFF OF.
EDIT I have been working on the script. There is a bug, if the player clicks it it opens. But it doesn't close when they walk away. It only closes when they are 15 studs away from the door and click on it. This should give you an idea.
local Door = script.Parent local openDistance = 15 --Must be 15 studs away local used = false function onClicked(playerWhoClicked) local dist = playerWhoClicked:DistanceFromCharacter(Door.Position) if dist <= openDistance and not used then used = true Door.CFrame = CFrame.new(34.6, 12.3, 105.1)*CFrame.Angles(0,math.rad(-90),0) elseif dist > openDistance and used then used = false Door.CFrame = CFrame.new(32.1, 12.3, 103.4)*CFrame.Angles(0,math.rad(0),0) end print(dist) end Door.ClickDetector.MouseClick:connect(onClicked)
Vector3 properties have a built-in collision check; if anything is touching it, it will be displaced to the top of the object it is colliding with.
So what property you will want to manipulate is CFrame. Coordinate framing will place a part virtually anywhere you want.
local Door = script.Parent function onClicked(playerWhoClicked) --opened Door.CFrame = CFrame.new(34.6, 12.3, 105.1) * CFrame.Angles(0, math.rad(90), 0) wait(2) --closed Door.CFrame = CFrame.new(32.1, 12.3, 103.4) * CFrame.Angles(0, math.rad(-90), 0) -- Strange coding IMO. This is not how I will usually script my doors. end Door.ClickDetector.MouseClick:connect(onClicked)
Be sure that the door is anchored.
Be aware that if you're multiplying or dividing CFrame values, you're doing so relative to its former position.
Contact me if you have any questions about the building portion of the door: if you want to see it animating, or have any other pleasant effects. There's lots of ways you can do that, but there are some pointers you might need to know.
To answer your question about efficient doors, the best way to do this is to adjust it relative to its position (not meaning the property).
local Door = script.Parent function onClicked(playerWhoClicked) --opened Door.CFrame = Door.CFrame * CFrame.new(4, 0, 0) * CFrame.Angles(0, math.rad(90), 0) wait(2) --closed Door.CFrame = Door.CFrame * CFrame.new(-4, 0, 0) * CFrame.Angles(0, math.rad(-90), 0) -- Strange coding IMO. This is not how I will usually script my doors. end Door.ClickDetector.MouseClick:connect(onClicked)
Let's break line 5 apart.
Door.CFrame - Changing the CFrame.
= Door.CFrame - Have the CFrame equal to itself; setting the "origin" of the CFrame.
CFrame.new(4, 0, 0) - Have the CFrame move 4 studs on the x-axis.
CFrame.Angles(0, math.rad(90), 0) - Have the CFrame rotate by 90° relative to its direction.
Still do not understand? I will happily answer your questions.