Good afternoon,
I keep getting a bad cast in the output whenever i click the ShirtBttn2 for the second function. The model is cloned to the NPC from ReplicatedStorage, however, it's position remains in the original position put in ReplicatedStorage, but not attactched to the Torso of the NPC. The bad cast call was in Line 59: "W.Part1 = C[i]". Anyone have any suggestions or ideas on how to fix this? Thank you, for your time.
Respectfully,
sparkevin
local ShirtBttn1 = sp:WaitForChild('Shirt1Button') local ShirtBttn2 = sp:WaitForChild('Shirt2Button') ShirtBttn1.MouseButton1Down:Connect(function() if workspace.CurrentCamera:findFirstChild("CustomCharacter") ~= nil and game.ReplicatedStorage:findFirstChild("Chest1") == nil then local g = game.ReplicatedStorage.Shirts.Chest1:clone() local d = game.Workspace.CurrentCamera:FindFirstChild("CustomCharacter") g.Parent = d local C = g:GetChildren() for i=1, #C do if C[i].className == "Part" or "Union" then local W = Instance.new("Weld") W.Part0 = g.Middle W.Part1 = C[i] local CJ = CFrame.new(g.Middle.Position) local C0 = g.Middle.CFrame:inverse()*CJ local C1 = C[i].CFrame:inverse()*CJ W.C0 = C0 W.C1 = C1 W.Parent = g.Middle end local Y = Instance.new("Weld") Y.Part0 = d["UpperTorso"] Y.Part1 = g.Middle Y.C0 = CFrame.new(0, -0.5, 0) Y.Parent = Y.Part0 end local h = g:GetChildren() for i = 1, # h do if h[i].className == "Part" or "Union" then h[i].Anchored = false h[i].CanCollide = false end end end end) ShirtBttn2.MouseButton1Down:Connect(function() if workspace.CurrentCamera:findFirstChild("CustomCharacter") ~= nil and game.ReplicatedStorage:findFirstChild("Chest2") == nil then local g = game.ReplicatedStorage.Shirts.Chest2:clone() local d = game.Workspace.CurrentCamera:FindFirstChild("CustomCharacter") g.Parent = d local C = g:GetChildren() for i=1, #C do if C[i].className == "Part" or "Union" then local W = Instance.new("Weld") W.Part0 = g.Middle W.Part1 = C[i] local CJ = CFrame.new(g.Middle.Position) local C0 = g.Middle.CFrame:inverse()*CJ local C1 = C[i].CFrame:inverse()*CJ W.C0 = C0 W.C1 = C1 W.Parent = g.Middle end local Y = Instance.new("Weld") Y.Part0 = d["UpperTorso"] Y.Part1 = g.Middle Y.C0 = CFrame.new(0, -0.5, 0) Y.Parent = Y.Part0 end local h = g:GetChildren() for i = 1, # h do if h[i].className == "Part" or "Union" then h[i].Anchored = false h[i].CanCollide = false end end end end)
Your if
condition (line 56) is incorrect and will always evaluate to true
even if C[i]
cannot be welded. Why? Although the condition may make sense if you read it like an english sentence, the computer understands something very different. Here's how the computer plays it out. The computer first evaluates the ==
operator. This turns the expression into true or "Union"
(child exists) or false or "Union"
(child doesn't exist). The value "Union"
is a truthy value meaning that this string evaluates to true. A truthy value in Lua is any value that is not false
or nil
and is implicitly coerced into a boolean in the context of a boolean expression.
As you can see the expression ultimately evaluates to true or true
or false or true
which will then result in true
no matter which scenario we are in. This means that even if the child is nonexistent or is of improper type, the if
condition will pass control flow onto the first block. The bad cast
error you get is thrown when you assign the value that has an invalid type to the property Part1
.
(for the future)
You mistakenly assumed that the ==
operator would take into consideration all three operands you supplied and return a result. This is wrong because ==
is an infix binary operator. Infix means that the operator appears between its operands and binary means that it takes in two operands. So the correct usage of the operator would be operand1 == operand2
. Remember that the computer cannot infer any extra magic so operand1 == operand2 and operand3
would check if operand1
is equal to operand2
and also if operand3
exists. There are other variants for operators including prefix and postfix for operator placement and unary, binary, and ternary for number of operands.
The direct solution would be to change the condition to C[i].ClassName == "Part" or C[i].ClassName == "Union"
. However, I highly recommend using the IsA
method because it's more flexible. More specifically, the expression if C[i]:IsA("BasePart")
should be used instead as it will check if C[i]
is any type of part rather then just the standard Part
type and Union
.