I’m working on my custom tool system which uses Motor6Ds to append some tools in the game to the character. Whenever a tool is given to a player it checks to see if there is a “ToolGrip” Motor6D as a child of the UpperTorso. If not, it creates one appropriately.
The only issue with this is due to some sort of obscure character loading quirk it stops functioning when the character is added. The applicable part of the tool giving function looks like this:
if player.Character then
local upperTorso = player.Character:FindFirstChild("UpperTorso")
if upperTorso then
if not upperTorso:FindFirstChild("ToolGrip") then
local toolGrip = Instance.new("Motor6D")
toolGrip.Name = "ToolGrip"
toolGrip.Part0 = upperTorso
toolGrip.Parent = upperTorso
-- test character model existence
coroutine.wrap(function()
while true do
print(toolGrip.Parent.Parent)
wait(0.3)
end
end)()
end
end
end
After the UpperTorso check passes you’d think that this reference to the character model would continue to exist, but it doesn’t. The test while loop prints the name of the character model once than starts to print nil. There is no code in my game that touches any aspect of the character loading process besides after the character has “added”. The result of this is the Motor6D continues to exist from its reference whilst being a descendant of nil. This then causes my code to halt later with the lack of the ToolGrip Motor6D … etc etc.
What’s going on here? What did I miss? All of this code is running after CharacterAdded is fired.
Try using player.CharacterAppearanceLoaded:Connect(function(character) instead of CharacterAdded and see if that works. Also if that’s all within the charadded event you can just do character.UpperTorso intead of player.Character. So I’m assuming your script might not be within the event and only after the event. You should put it within because if its only after then the code after it will fire before the charadded event. It’s because an event wont make the script wait to read any code after it and only the ones inside it.
game.Players.PlayerAdded:Connect(function(plr)
plr.CharacterAdded:Connect(function(char)
local upperTorso = char:FindFirstChild("UpperTorso")
if not upperTorso:FindFirstChild("ToolGrip") then
local toolGrip = Instance.new("Motor6D")
toolGrip.Name = "ToolGrip"
toolGrip.Part0 = upperTorso
toolGrip.Parent = upperTorso
-- test character model existence
coroutine.wrap(function()
while true do
print(toolGrip.Parent.Parent)
wait(0.3)
end
end)()
end
end)
end)
I don’t really know what was wrong with your code but I added CharacterAdded and PlayerAdded events and removed some checks and seems to work fine.
@TheCreatorBenn
After some testing, this seems to work. I had wondered if it was some janky behavior with the avatar appearance being created that was messing with all kinds of things. It would appear that this was the case - thank you for the solution.
@Icey_CD
I’m not sure why it would work in that case. Did you double check in the explorer that the ToolGrip Motor6D is indeed a child of the UpperTorso?
It is possible his worked because he has less things in his game and so his character loaded faster. So then everything of it loaded in time, but yours Im gonna assume has more stuff and thats why it needed the extra check to make sure the char has fully loaded. I don’t really know tbh but if the code is the same and his worked and yours didn’t then that is possible.
Considering how my game is basically just scripts there shouldn’t be too much going on. This problem is quite confusing because a similar system in another game of mine doesn’t have this issue. There is, of course, all kinds of variability to keep in mind though.
In the instance of my game waiting for the avatar appearance to load isn’t much of a bother anyways, so I suppose it will have to do.