Part に触れている他のパーツを調べるには、GetTouchingParts というものを使えば良いのですが、なぜか単純に呼び出しただけでは正常に動作しないようです。以下のようなプログラムを組みことで正常に動作することが確認できました。この関数に調べたいPartを指定すれば、触れているすべてのパーツが返ります。
local function getTouchingParts(part)
local connection = part.Touched:Connect(function() end)
local results = part:GetTouchingParts()
connection:Disconnect()
return results
end
モデルのWeld化
アンカー設定されているモデルは、アセット内のバズーカ砲などでは破壊できないのがほとんどです。またアセット内のモデルはアンカー設定されているものが多いようです。そこで、上記関数の使用例として、アンカー設定されているパーツで作られたモデルを接着(Weld)し、アンカーを解除するプログラムを作成してみます。
local function weldParts(part,parts)
for _,v in pairs(parts) do
local weld = Instance.new("WeldConstraint")
weld.Part0 = part
weld.Part1 = v
weld.Parent = v
end
end
local function weldModel(model)
local descendants = model:GetDescendants()
for _, v in pairs(descendants) do
if v:IsA("BasePart") and v.Anchored == true then
local parts = getTouchingParts(part)
weldParts(v,parts)
v.Anchored = false
end
end
end
getAllParts(モデル)
少し離れていても接着させる方法
上記のプログラムでは、パーツ同士が完全に触れていないと接着されません。そこで、パーツ同士が少し離れていても接着できるようなプログラムを作成してみました。
パーツのサイズを少し大きくし、元も戻して接着させます。この方法ですと、GetTouchingParts は正しく動作するようです。
local distance = 0.1 -- 許容範囲
local function weldModel(model)
local descendants = model:GetDescendants()
for _, v in pairs(descendants) do
if v:IsA("BasePart") and v.Anchored == true then
v.Size = v.Size + Vector3.new(distance,distance,distance)
wait()
weldParts(v,v:GetTouchingParts())
v.Size = v.Size + Vector3.new(-distance,-distance,-distance)
v.Anchored = false
end
end
end
getAllParts(モデル)