Since luduvo fixed AMD support, I’ve finally been able to use luduvo studio. I tried making some stuff, but I found that welding is broken. So I thought it would be a nice first scripting project in luduvo to make a welding script. I wasn’t able to stress test this setup in studio because luduvo studio decided that my character shouldn’t move around, so I’m just stuck floating in the air forever. But here is what I came up with:
Edit: THE CHARACTER IS STILL BROKEN. I’ve resorted to putting parts with varying mass above the welded groups to test if it breaks. And now it’s not just the character breaking, it studio every time I try and load a project… Trying to work with Luduvo studio is just cancerous at this point
V1, not very good
local weldPart1 = self
weldPart2 = weldPart1.Parent:FindFirstChild("weldPart2") -- the name of the part you want to weld to. In this instance, both parts are in a group, and the part with the server script is named "weldPart1" and the other part is named "weldPart2".
local difference = -4 -- weldPart2 is -4 studs away from weldPart2 on the x-axis. if you have more differences, that means more difference variables : )
function Update(dt)
if weldPart2 and weldPart2.Name == "weldPart2" then
local pos = weldPart1.Position
local rot = weldPart1.Orientation
weldPart2.Position = Vector3.new(pos.X + difference, pos.Y, pos.Z) -- move the welded part to the right spot using the difference variables
weldPart2.Orientation = rot -- update orientation. Probably needs fixing.
end
end
V2, Automatic welding
--[[
Steps on how to use it:
1: insert server script into the model that has all the parts you want welded in.
2: paste the script into the server script
3: enjoy some pseudo-welding
Note: Before doing all of this, I didn't even check to see if you can weld things using Luduvo's welding system that's already in place with Lua code. And I think that the only thing broken about it is the user interface, not the underlying code within it. So I think the code I made is basically useless, so maybe I'll look into just making an automatic welding script with code that uses Luduvo's actual welding system and not my own crappy version. I haven't tested to see if that way works, I just read someone on the forums that said you can do it that way.
--]]
local partTable = {} -- stores da parts
local partOffsets = {} -- Dictionary to store offsets
local isInitialized = false
local function scanForParts(instance)
for i, child in instance:GetChildren() do
local subChildren = child:GetChildren()
if #subChildren == 0 then -- if it has 0 children, then it has to be a part, not a group.
table.insert(partTable, child)
else
scanForParts(child) -- it has some parts in it, I guess we assume it's a group. Now, tell em' to bring out the whole ocean.
end
end
end
scanForParts(self)
--================================================================================--
-- Main logic & setup:
--================================================================================--
local CUSTOM_ORIGIN_NAME = "origin" -- You input the name of the part you want to have collisions and physics here!!!!!!!!!!!!!!!!!!11!1!1
local originPart = nil
for i, part in ipairs(partTable) do
if part.Name == CUSTOM_ORIGIN_NAME then
originPart = part
table.remove(partTable, i) -- remove the custom origin part from the table so it doesn't calculate an offset to itself, because that would be dumb.
break
end
end
if not originPart then -- picks a random origin part if the one you chose cannot be found...
originPart = table.remove(partTable, 1)
if originPart then
warn(originPart.Name .. " cannot be found. Did you spell it right?")
warn("Due to the potential unwanted origin part, you may need to turn all collider values to automatic in your group...")
end
end
if originPart then -- this part basically preps the orientation for trigonometry math, finds the distance difference between the secondaryPart and the originPart, and all that mumbo jumbo.
local originPos = originPart.Position
local originRot = originPart.Orientation
local startRadY = math.rad(originRot.Y) -- Convert starting angle to radians
local cosY = math.cos(startRadY)
local sinY = math.sin(startRadY)
for i = 1, #partTable do
local secondaryPart = partTable[i]
if secondaryPart then
local worldPosOffset = secondaryPart.Position - originPos
local localX = worldPosOffset.X * cosY + worldPosOffset.Z * sinY
local localZ = -worldPosOffset.X * sinY + worldPosOffset.Z * cosY
local posOffset = Vector3.new(localX, worldPosOffset.Y, localZ)
local rotOffset = secondaryPart.Orientation - originRot
secondaryPart.Anchored = true -- allows to prioritize physics for the origin part, and not the secondary parts.
secondaryPart.Collider = "None" -- fixes part collisions which can glitch out the unanchored object that is welded together.
partOffsets[secondaryPart] = {
posOffset = posOffset,
rotOffset = rotOffset
}
end
end
end
function Update(dt) -- this is the core updater where all the logic does the logic stuff for every single frame.
if originPart then
local originPos = originPart.Position
local originRot = originPart.Orientation
local currentRadY = math.rad(originRot.Y) -- convert the current orientation to radians for the trigonometry functions for the origin part
local cosY = math.cos(currentRadY)
local sinY = math.sin(currentRadY)
if not isInitialized then
for secondaryPart, _ in pairs(partOffsets) do
secondaryPart.Anchored = true -- allows to prioritize physics for the origin part, and not the secondary parts a second time just to be sure it actually did it...
secondaryPart.Collider = "None" -- fixes part collisions which can glitch out the unanchored object that is welded together a second time just to be sure it actually did it...
end
isInitialized = true
end
for secondaryPart, data in pairs(partOffsets) do
local localOffset = data.posOffset
local rotatedX = localOffset.X * cosY - localOffset.Z * sinY -- rotates the local offsets into the world space to match the rotation direction
local rotatedZ = localOffset.X * sinY + localOffset.Z * cosY -- I hated this part.
secondaryPart.Position = Vector3.new(originPos.X + rotatedX, originPos.Y + localOffset.Y, originPos.Z + rotatedZ)
secondaryPart.Orientation = originRot + data.rotOffset
end
end
end
What using Luduvo's welding system would look like
--[[
So, as you can see it's much simpler to do it this way, coding wise. But when you use it, you will find that
it is way less stable than the system I have in place in V2. If you have large builds in place with
overlapping parts, the model will simply fling apart and glitch out.
You could hypothetically fix this by removing collisions for the parts in the model, but that doesn't seem
to work with this.
So, the takeaway is to just use V2 of my code, this is simply an example of how it would work.
Who knows, this code might be useful some day if they ever decide to fix welding.
--]]
local partTable = {}
local function scanForParts(instance)
for i, child in instance:GetChildren() do
local subChildren = child:GetChildren()
if #subChildren == 0 then
table.insert(partTable, child)
else
scanForParts(child)
end
end
end
scanForParts(self)
local main = partTable[1]
local function CreateWeldsAndWeld()
if not main then return end
for i, Part in ipairs(partTable) do
if Part ~= main then
Part:AddComponent("Weld")
Part.BreakForce = 0
Part.Other = main
end
end
end
CreateWeldsAndWeld()