Сценарий lua на roblox, который перемещает модель вверх?

У меня есть модель под названием дверь Внутри у меня есть BoolValue с именем Open У меня есть модель под названием Top, в которой есть все дверные блоки с именами Work Mabey Comeon и Proboblynot И у меня есть Block, который при прикосновении должен заставлять Top двигаться вверх

Прямо внутри двери у меня есть этот скрипт

door = script.Parent
open = door.Open
Top = door.Top

opener = 18
speed = 100
steps = speed

startl = Top.CFrame

function MoveDoorToCFrame(cfrm,dr)
    dr.Work.CFrame = cfrm
dr.Mabey.CFrame = dr.Work.CFrame * CFrame.new(0,-7.2,0)
dr.Comeon.CFrame = dr.Work.CFrame * CFrame.new(0,10.8,0)
dr.Problynot.CFrame = dr.Work.CFrame * CFrame.new(0,10.8,0)
end

function Update()
if speed/steps < 0.5 then
    calc = 1-math.cos(math.rad((-90/speed)*steps*2))
else
    calc = 1+math.sin(math.rad((90/speed)*((speed/2)-steps)*2))
end
MoveDoorToCFrame(startl * CFrame.new(0,(calc/2)*opener,0),Top)
end

Update()
while true do
wait()
if not open.Value and steps < speed then
    steps = steps + 1
    Update()
elseif open.Value and steps > 0 then
    steps = steps - 1
    Update()
end
end 

Внутри кнопки, которая должна активироваться при прикосновении, у меня есть

script.Parent.Touched:connect(function()
script.Parent.Parent.Open.Value = not script.Parent.Parent.Open.Value
end)

script.Parent.Parent.Open.Changed:connect(Update)
Update()

Если вы знаете, как это исправить, мы будем благодарны.


person Crazynerd314    schedule 21.01.2014    source источник


Ответы (4)


Ваш код действительно нуждается в исправлении.

Вы НЕ должны использовать бесконечный цикл, чтобы ваши вещи работали (если только это не единственный способ). Вам лучше основывать действия на событиях.

Подумайте об использовании этого:

Состав:

Door [Model]
    DoorScript [Script]
    Button [Part]
    DoorOpen [BoolValue]
    Top [Model]
        Mabey [Part]
        Comeon [Part]
        Problynot [Part]

DoorScript:

local Model = script.Parent
local Door = Model.Top
local Button = Model.Button
local DoorOpen = Model.DoorOpen

local Offset = 0
local ToOffset = 100
local Direction = 1

local StepLength = 0.1

local Moving = false

function StartMoving()
    if Moving then return end
    Moving = true
    while (DoorOpen.Value and Offset ~= ToOffset) or (not DoorOpen.Value and Offset ~= 0) do
        local Change = Offset
        Offset = math.max(0,math.min(ToOffset,Offset + StepLength * (DoorOpen.Value and 1 or -1)))
        Change = Offset - Change
        Top:TranslateBy(Vector3.new(0,Change,0))
        wait()
    end
    Moving = false
end
StartMoving()
DoorOpen.Changed:connect(StartMoving)

local Debounce = false
Button.Touched:connect(function()
    if Debounce then return end
    Debounce = true
    DoorOpen.Value = not DoorOpen.Value
    wait(4)
    Debounce = false
end)

Возможно, вы захотите отрегулировать скорость tho.

person ZombieSpy    schedule 22.02.2014
comment
Мне очень жаль, что у меня был другой проект, и я забыл об этом, когда я увидел эти ответы, я был так рад, что вы все помогли, я пошел с вашим сценарием, и потребовалось несколько попыток, но у меня все заработало. - person Crazynerd314; 11.03.2014
comment
Мне потребовалась целая вечность, чтобы оштрафовать там, где было написано Top: TranslateBy, что это должна быть Door, а не верхняя, но спасибо за помощь, это подняло мой боевой дух в 10 раз. Палец вверх. - person Crazynerd314; 11.03.2014

Обновление, ноябрь 2015 г .:

Использование PrimaryPart

С момента написания этого поста ROBLOX сильно изменился в отношении API. Чтобы переместить модель, как запрошено, вы должны установить свойство PrimaryPart модели на центральную часть внутри модели. Это будет действовать как origin для движений модели.

Затем вы можете использовать model:SetPrimaryPartCFrame(cframe) для установки CFrame модели. Вы также можете получить это свойство с помощью model:GetPrimaryPartCFrame(), хотя я считаю, что это всего лишь сокращенный метод для model.PrimaryPart.CFrame.

В коде это будет выглядеть так:

-- Set PrimaryPart:
MODEL.PrimaryPart = MODEL.SomeCentralPart
...

-- CFrame movement:
local movement = CFrame.new(0, 10, 0)

-- Move the model:
MODEL:SetPrimaryPartCFrame(MODEL:GetPrimaryPartCFrame() * movement)

Вариант А. Используйте методы модели

Я думаю, вы делаете это намного труднее, чем должно быть. Всякий раз, когда вы сталкиваетесь с подобной проблемой, обязательно проверяйте предоставленные текущие API. Объект ROBLOX Model содержит изящный метод TranslateBy, который принимает аргумент Vector3 для перевода модели.

Использование MODEL:TranslateBy(Vector3) аналогично перемещению модели через CFrame, поскольку оно игнорирует столкновения.

Другой альтернативой является MODEL:MoveTo(Vector3), который перемещает всю модель в заданную мировую позицию Vector3. Обратной стороной этого является то, что он действительно конфликтует.

Один из способов получить тот же эффект MoveTo, но без столкновений, можно сделать с помощью метода TranslateBy:

MODEL:TranslateBy(Vector3Position - MODEL:GetModelCFrame().p)

Вариант Б. Напишите пользовательскую функцию для управления CFrame модели

Другой альтернативой было бы полностью манипулировать CFrame всей модели. Для этого вы можете написать умную функцию, которая будет перемещать всю модель относительно «исходной» точки. Это похоже на перемещение фигур по сетке с учетом их точек и начала координат, за исключением трех измерений. Однако, используя встроенные функции ROBLOX, это намного проще.

Хороший способ сделать это - написать функцию, которая позволит вам фактически присвоить значение CFrame всей модели. Другой способ - разрешить перевод через CFrame.

Вот пример:

function ModelCFrameAPI(model)

    local parts = {} -- Hold all BasePart objects
    local cf = {} -- API for CFrame manipulation

    do
        -- Recurse to get all parts:
        local function Scan(parent)
            for k,v in pairs(parent:GetChildren()) do
                if (v:IsA("BasePart")) then
                    table.insert(parts, v)
                end
                Scan(v)
            end
        end
        Scan(model)
    end

    -- Set the model's CFrame
        -- NOTE: 'GetModelCFrame()' will return the model's CFrame
        -- based on the given PrimaryPart. If no PrimaryPart is provided
        -- (which by default is true), ROBLOX will try to determine
        -- the center CFrame of the model and return that.
    function cf:SetCFrame(cf)
        local originInverse = model:GetModelCFrame():inverse()
        for _,v in pairs(parts) do
            v.CFrame = (cf * (originInverse * v.CFrame))
        end
    end

    -- Translate the model's CFrame
    function cf:TranslateCFrame(deltaCf)
        local cf = (model:GetModelCFrame() * deltaCf)
        self:SetCFrame(cf)
    end

    return cf
end


-- Usage:
local myModel = game.Workspace.SOME_MODEL
local myModelCF = ModelCFrameAPI(myModel)

-- Move to 10,10,10 and rotate Y-axis by 180 degrees:
myModelCF:SetCFrame(CFrame.new(10, 10, 10) * CFrame.Angles(0, math.pi, 0))

-- Translate by 30,0,-10 and rotate Y-axis by 90 degrees
myModelCF:TranslateCFrame(CFrame.new(30, 0, -10) * CFrame.Angles(0, math.pi/2, 0))
person Stephen Leitnick    schedule 19.02.2014

Это можно использовать для перемещения моделей, попробуйте добавить что-то подобное в свой код. Это более динамично.

a = Workspace.Model

for i=0.1,40 do
    for i,v in pairs(a:getChildren()) do
        if v:IsA("Part") then
            v.CFrame = CFrame.new(v.CFrame + Vector3.new(0,0.1,0))
        else print("Not a part")
        end
    end
end
person tyler5819    schedule 30.01.2014

Это может быть сложно.
Возможно, вам стоит поискать бесплатные модели для этого, если только вышеперечисленные люди не заставят его работать. Однако у меня есть сценарий для перемещения модели:

game.Workspace.Model:MoveTo(Vector3.new(0,0,0))
person Ricu22    schedule 21.11.2017