Hello, I’ve currently got an issue with my code, it currently " works " but is quiet patched up and frankly poorly made. So some suggestions and ideas for a fix would be amazing.
The script is supposed to give the user a Rig. ( Any part I need to weld ) when they join, the whole checking if they join and if they’re supposed to have a rig is complete, now the issue is with my current method for applying the rig it’s failing to properly attach and instead appears under the map and still moves with the player.
A solution to this is to simply reset as to why I’ve included a respawn line however I’d ideally like to remove that all together.
Module
if SelectedRig then
for _, SelectedRig in pairs(SelectedRig.Rigs) do
wait(1)
local Rig = SelectedRig:Clone()
Rig.Parent = Char
local Children = Rig:GetChildren()
for i=1, #Children do
local W = Instance.new("Weld")
W.Part0 = Rig.Middle
W.Part1 = Children[i]
local CJ = CFrame.new(Rig.Middle.Position)
local C0 = Rig.Middle.CFrame:inverse()*CJ
local C1 = Children[i].CFrame:inverse()*CJ
W.C0 = C0
W.C1 = C1
W.Parent = Rig.Middle
local Y = Instance.new("Weld")
Y.Part0 = Char[Rig.Middle.Root.Value]
Y.Part1 = Rig.Middle
Y.C0 = CFrame.new(0, 0, 0)
Y.Parent = Y.Part0
Children[i].Anchored = false
Children[i].CanCollide = false
end
end
end
end
Server
local Rig = require(script.Rigs)
local Players = game:GetService("Players")
game.Players.PlayerAdded:Connect(function(Player)
wait(2)
Player.Character.Humanoid.Health = 0
Player.CharacterAdded:Connect(function(Char)
Rig(Player,Char)
end)
end)
First off on your server function is to try making a catcher function instead of killing the player when they join. The 2-second wait also presents an edge case in the instance that CharacterAdded is not fired within that time, which is why it should be CharacterAdded:Wait() instead.
As far as the catcher function goes, it essentially equates to running a function on a potentially existing character as well as any that gets added.
local Players = game:GetService("Players")
local attachRig = require(script.Rigs)
local function onCharacterAdded(character)
attachRig(character)
-- Use Players.GetPlayerFromCharacter to get player in module; don't pass instance
end
Players.PlayerAdded:Connect(function (Player)
Player.CharacterAdded:Connect(onCharacterAdded)
if Player.Character then
onCharacterAdded(Player.Character)
end
end)
The second thing is that when it comes to rig/morph giving code, I absolutely never perform a full-extents weld operation at run time. I always weld my assemblies in Studio and if I need to attach them, I create a weld between the root of the assembly and the character without setting C0/C1, thus snapping in place. The root of the assembly is a copy of the part I want to weld it to, but invisible.
In your case, since you seem to be welding in place, I would suggest using WeldConstraints. If all your parts are prepositioned but not prewelded, you can use WeldConstraints to join them. Why WeldConstraints though? You don’t have to worry about offsets, they join things in place statically.
Do not parent until you’re ready to attach the rig. Once you are, parent and create the weld. You’ve also got some variable shadowing that needs to be fixed. Here is a new set of code you could work with:
if SelectedRig then
for _, RigItem in pairs(SelectedRig.Rigs) do
local RigPiece = RigItem:Clone()
local RigMiddle = RigPiece.Middle
for _, RigPart in pairs(RigPiece:GetDescendants()) do
if RigPart:IsA("BasePart")
local WeldConstraint = Instance.new("WeldConstraint")
WeldConstraint.Part0 = RigMiddle
WeldConstraint.Part1 = RigPart
WeldConstraint.Parent = WeldConstraint.Part1
RigPart.Anchored = false
RigPart.CanCollide = false
end
end
RigPiece.Parent = Char
local Weld = Instance.new("Motor6D")
Weld.Part0 = RigMiddle
Weld.Part1 = Char[RigMiddle.Root.Value]
Weld.Parent = Weld.Part1
end
end