Обновление, ноябрь 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