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

Most efficient way of opening a gate?

Asked by 10 years ago

I am currently building a model of the gates of Arendelle Castle (http://i58.servimg.com/u/f58/18/36/77/95/arende10.jpg), however I have run into a snag with getting them to open and close. A friend of mine provided me with a script she got from somewhere else, however it works imperfectly (http://i58.servimg.com/u/f58/18/36/77/95/arende11.jpg). As can be seen in that image, the gates do not open smoothly.

Here's the code:

local MoveBy = .1
local waittime = 0--wait()
local Rep = 40 --Take the studs it needs to move by, and multiply by the Variable MoveBy to get the movement. 

local MoveBy2 = math.rad(1)
local waittime2 = 0--wait()
local NotMoveBy = math.rad(0)

local OldType = 3
local Debounce = false
local Open = false
--I'd like to say that Anaminus made this, but since it's a tool, I can use it?
function RotateModel(model,center,axes,inc,step)
    local origin = {}
    for _,child in pairs(model:GetChildren()) do
        if child:IsA"BasePart" then
            origin[child] = center:toObjectSpace(child.CFrame)
        end
    end
    for i = 1,inc or 1 do
        center = center  * CFrame.fromEulerAnglesXYZ(unpack(axes))
        for part,cf in pairs(origin) do
            part.CFrame = center:toWorldSpace(cf)
        end
        if step then wait(step) end
    end
end


function OpenDoors(type) --type 1 = slide, type 2 = turn.  type 3 = turn backwards
if type == 1 then
    delay(0, function() --opens right
        for i=1, Rep, 1 do 
            for a, b in pairs(script.Parent.Right:getChildren()) do
                if b:isA("BasePart") then
                    b.CFrame = b.CFrame + Vector3.new(0, 0, -MoveBy)
                end
            end
            wait(waittime)
        end
    end)
    for i=1, Rep, 1 do --Opens left
        for a, b in pairs(script.Parent.Left:getChildren()) do
            if b:isA("BasePart") then
                b.CFrame = b.CFrame + Vector3.new(0, 0, MoveBy)
            end
        end
        wait(waittime)
    end
elseif type == 2 then
delay(0, function() RotateModel(script.Parent.Right, script.Parent.Right.Hinge.CFrame, {NotMoveBy,NotMoveBy, MoveBy2}, 90, waittime2) end)
RotateModel(script.Parent.Left, script.Parent.Left.Hinge.CFrame, {NotMoveBy,NotMoveBy, -MoveBy2}, 90, waittime2)
elseif type == 3 then
delay(0, function() RotateModel(script.Parent.Right, script.Parent.Right.Hinge.CFrame, {NotMoveBy,NotMoveBy, -MoveBy2}, 90, waittime2) end)
RotateModel(script.Parent.Left, script.Parent.Left.Hinge.CFrame, {NotMoveBy,NotMoveBy, MoveBy2}, 90, waittime2)
end
end 

function CloseDoors(type) --type 1 = slide, type 2 = turn.  type 3 = turn backwards
if type == 1 then
    delay(0, function() --opens right
        for i=1, Rep, 1 do 
            for a, b in pairs(script.Parent.Right:getChildren()) do
                if b:isA("BasePart") then
                    b.CFrame = b.CFrame + Vector3.new(0, 0, MoveBy)
                end
            end
            wait(waittime)
        end
    end)
    for i=1, Rep, 1 do --Opens left
        for a, b in pairs(script.Parent.Left:getChildren()) do
            if b:isA("BasePart") then
                b.CFrame = b.CFrame + Vector3.new(0, 0, -MoveBy)
            end
        end
        wait(waittime)
    end
elseif type == 2 then
delay(0, function() RotateModel(script.Parent.Right, script.Parent.Right.Hinge.CFrame, {NotMoveBy,NotMoveBy, -MoveBy2}, 90, waittime2) end)
RotateModel(script.Parent.Left, script.Parent.Left.Hinge.CFrame, {NotMoveBy,NotMoveBy, MoveBy2}, 90, waittime2)
elseif type == 3 then
delay(0, function() RotateModel(script.Parent.Right, script.Parent.Right.Hinge.CFrame, {NotMoveBy,NotMoveBy, MoveBy2}, 90, waittime2) end)
RotateModel(script.Parent.Left, script.Parent.Left.Hinge.CFrame, {NotMoveBy,NotMoveBy, -MoveBy2}, 90, waittime2)
end
end 

function OnActivation()
if not debounce then
debounce = true
if Open then
CloseDoors(OldType)
Open = false
else
if script.Parent.Open.Type.Value >= 1 and script.Parent.Open.Type.Value <= 3 then
    OpenDoors(math.floor(script.Parent.Open.Type.Value))
    OldType = math.floor(script.Parent.Open.Type.Value)
    Open = true
else
print("Type invalid")
end
end
script.Parent.Open.Value = false
wait()
debounce = false
else
print("Already Opening or closing a door")
end
end

for a, b in pairs(script.Parent:GetChildren()) do
    if b and b:IsA("BasePart") and b.Name == "Sensor" then
        b.Touched:connect(function(p)
            if p and p.Parent and p.Parent:FindFirstChild("Humanoid") then
                OnActivation()
            end
        end)
    end
end

for a, b in pairs(script.Parent.Left:GetChildren()) do
    if b and b.Name == "ClickSensor" and b:FindFirstChild("ClickDetector") then
        b.ClickDetector.MouseClick:connect(function(p)
            OnActivation()
        end)
    end
end
for a, b in pairs(script.Parent.Right:GetChildren()) do
    if b and b.Name == "ClickSensor" and b:FindFirstChild("ClickDetector") then
        b.ClickDetector.MouseClick:connect(function(p)
            OnActivation()
        end)
    end
end

script.Parent.Open.Changed:connect(function(Value) OnActivation() end)

I suspect the problem lies within the RotateModel function. Each half of the gate has 80 pieces, and this function calculates the position for each part each time the gate's position is updated. It looks fine in Studio's Play Solo mode, but not in the actual game. What I want to know is this: Is it possible to make this script more efficient, and if not, what would be a better alternative to calculating CFrames? I've tried using a BodyGyro, but that rotated the gate about its center instead of the hinge piece.

Any help you can give me would be appreciated. If you want to see the problem in person, you can go to this game: http://www.roblox.com/Kingdom-of-Arendelle-place?id=155458964 The gate in question is the one with grey bricks and wood columns at the far end of the bridge.

1 answer

Log in to vote
0
Answered by
JuHDude 25
10 years ago

I experienced a very similar problem when trying to move a bunch of parts smoothly, I looked everywhere to find a smoother method and all that I tried still had the same issue. So if anyone could come up with a solution it would be much appreciated.

I am guessing it is something to do with roblox itself, I might be wrong though.

Sorry If I couldn't be of much help.

Ad

Answer this question