Hello there. You might have been referred to this article from someone else, or you’re stumbling across it on the Developer Forum because you were searching for a solution of this caliber.
If you were referred, we’re doing things a bit differently here in terms of script, and other things. Some of the content from the Old Post might still be used, but I wanted to revamp this tutorial because my thought process was all over the place and I was constantly making readjustments to it. I don’t want to make a new post because this one is too well known.
(Old Post) Version 1 (Outdated as of 2021/09/24)
For most developers making small games, and using tools inside those games, you’ll run into some issues with animating a Tool’s
Handle part. I’m not the greatest scripter, nor am I the greatest animator but this tutorial will certainly help some folks avoid RemoteEvents, and LocalScripts.
I wanted to make a simple and easy tutorial that follows the similar goal of this tutorial, but in a way that exploiters cannot abuse RemoteEvents, and local scripts as @Headstackk mentioned in that tutorial. However, the Motor6D can still be abused in some forms, but probably not as bad as a RemoteEvent.
Disclaimer: By following this tutorial, I assume you already know how to Load an Animation onto your character by using a script, and that you also know how to Upload Animations to Roblox.
Let us begin!
Step 1: Insert a dummy into your Roblox Studio Project. For this part of the tutorial, we’ll be inserting an R6 avatar. Go into the
Plugin tab of Roblox Studio, then find and select the button labeled
Build Rig with the text
Rig Builder below it. The icon looks like a little Roblox Avatar
Then right after that, make sure you switch the R15 option to R6 when the GUI with the Blue buttons comes up. Make sure you click on “Block Rig” or whatever you’re comfortable with after that. It won’t affect this animation in anyway, as all you need is some R6 rig to animate on.
Major credits to this tutorial for the animating with a tool portion, and Motor6D’s, by @H_mzah. I will be using only ONE part for this tutorial which is the Handle, but they explain it a lot better if you’re using multiple parts for your tool. I won’t be going over welding multiple parts, so please read their article.
Step 2: Once the Rig is inserted into the workspace, move your tool inside the model of the Dummy, and remove all other scripts or animations from that tool, leaving only the handle behind with it’s mesh still inside of it. Then, move the handle out of the tool, and back into the Dummy’s character, then group that Handle you just took out of your tool and name that model whatever you want. In this case, I did “Bat”. Make sure to also delete the leftover tool object. For an easier understanding, look at this video clip:
p.s I grouped both the Dummy and Tool together too easily find where they are. After you’re done moving the tool, just ungroup the model, and NOT the dummy.
Step 3: Insert a Motor6D into the Model of the Dummy. You can do this by pressing the + icon beside the dummies name in the
Step 4: Click on the Motor6D in the Dummy, and set the
Part0 to the Right Arm of the Dummy, and set the
Part1 to the Handle of your tool that was inside the Model you created for your tools handle earlier. (in my case, the model is called “Bat”) This is all done through the
Keep in mind, after you do this, the tool will move to the center of your Dummies arm, which is perfectly normal.
This is a good sign you did things correctly! If you didn’t get to this point by following the tutorial, please refer to @H_mzah’s tutorial as they explain this a lot better! Link to it can be found above in a spoilered text field.
Step 5: Publish your animation once you’re done animating with your tool, like normal. By following this tutorial, I assume you know how to animate, and upload animations to Roblox. Once you upload it, the animation will contain a
Keyframe for the handle. This will come useful for when you’re scripting your animation for your tool.
Now it’s time for more of the difficult part…
Step 6: Locate
Explorer, then insert a Server Script into it, and call it
Motor6DHandler. You can insert a script by pressing the + icon, and typing “Script” then hitting enter.
It should look like this after!
Step 7: Insert a Motor6D, and a BoolValue into the
Motor6DHandler script you just created. Again, using + then typing
Motor6D into the type box, then hitting enter. Then do the same, but typing
BoolValue instead. IMPORTANT! Make sure you name the BoolValue “MotorCheck”.
Step 8: Open up the Motor6DHandler Script, and type the following, or copy it directly. Comments have been left for understanding purposes:
-- You want to reference the BoolValue, the Motor6D, AND the name of your tool. Tool = script.Parent:WaitForChild("Average Baseball Bat") MotorCheck = script.MotorCheck Motor6D = script.Motor6D --[[ Then you want to call a function so when you equip the tool, this script will activate, and set the Motor6D's Part0, and Part1 to their respective parts ]] Tool.Equipped:Connect(function() Motor6D.Part0 = script.Parent:WaitForChild("Right Arm") Motor6D.Part1 = Tool:WaitForChild("Handle") --[[ Since the 2 lines of code above do not run more than once when you equip the tool for some reason, you want to put an if statement to check to see if the Bool was set to true which has been done at the END of the equipped function ]] if MotorCheck == true then Motor6D.Part0 = script.Parent:WaitForChild("Right Arm") Motor6D.Part1 = Tool:WaitForChild("Handle") end --[[ Unfortunately for us, Roblox Tools like to create a weld automatically to the Right Arm EVERYTIME you equip the tool, and that can stop the Motor6D from doing it's work. So below, we wait for the RightGrip to be added, then delete it. Easy peasy! ]] RightArmGrip = script.Parent["Right Arm"]:WaitForChild("RightGrip") wait() RightArmGrip:Destroy() MotorCheck = true end) --[[ This part of the script can be very crucial, or else the Motor6D might break. When you unequip the tool, the Part0 and Part1 values are set to nil (nothing) to prevent the Motor6D from breaking on next equip. ]] Tool.Unequipped:Connect(function() Motor6D.Part1 = nil Motor6D.Part0 = nil end) -- And that is all for the script! --
What this script will do, is since
StarterPlayerScripts adds any scripts you put inside of it to your characters model, it will be able to use the Motor6D inside of the Motor6DHandler script, and setting the
Part1 to the correct parts. This is all done with only ONE script, but you’ll need to script it so when you equip, click, or unequip an animation plays, but you do that for the tool you created, and that you’re having this issue with. I stated at the top of this tutorial that I won’t be teaching how to script a :LoadAnimation() script.
THAT’S IT! YOU SHOULD BE ABLE TO PLAY THE HANDLE KEYFRAME WITH YOUR TOOLS ANIMATION! HERE’S AN EXAMPLE OF BEFORE BEING ABLE TO DO SO, AND AFTER:
Is there any error with following this tutorial? Does something not make sense? Please reply to me, and I’ll see what I can do for you. As far as scripting goes, I went with the best of my knowledge, and since I’m new to Roblox Scripting, some stuff inside the Motor6DHandler script may or may not be practical. I’m open to any feedback on this, or any edits I should make. I tried to be as clear and concise as possible, trying to include every step of the way.
This tutorial also works with R15, but for the Motor6DHandler, you’ll have to change it to this:
-- You want to reference the BoolValue, the Motor6D, AND the name of your tool. Tool = script.Parent:WaitForChild("Average Baseball Bat") MotorCheck = script.MotorCheck Motor6D = script.Motor6D --[[ Then you want to call a function so when you equip the tool, this script will activate, and set the Motor6D's Part0, and Part1 to their respective parts ]] Tool.Equipped:Connect(function() Motor6D.Part0 = script.Parent:WaitForChild("RightHand") Motor6D.Part1 = Tool:WaitForChild("Handle") --[[ Since the 2 lines of code above do not run more than once when you equip the tool for some reason, you want to put an if statement to check to see if the Bool was set to true which has been done at the END of the equipped function ]] if MotorCheck == true then Motor6D.Part0 = script.Parent:WaitForChild("RightHand") Motor6D.Part1 = Tool:WaitForChild("Handle") end --[[ Unfortunately for us, Roblox Tools like to create a weld automatically to the Right Hand EVERYTIME you equip the tool, and that can stop the Motor6D from doing it's work. So below, we wait for the RightGrip to be added, then delete it. Easy peasy! ]] RightHandGrip = script.Parent.RightHand:WaitForChild("RightGrip") wait() RightHandGrip:Destroy() MotorCheck = true end) --[[ This part of the script can be very crucial, or else the Motor6D might break. When you unequip the tool, the Part0 and Part1 values are set to nil (nothing) to prevent the Motor6D from breaking on next equip. ]] Tool.Unequipped:Connect(function() Motor6D.Part1 = nil Motor6D.Part0 = nil end) -- And that is all for the script! --
Hey, hello, yes it’s me, Void_Xiety. The person who’s probably criticized one of your posts (if you asked) or helped solve one of your scripting support issues.
Today I’m offering a revamped tutorial from the last that, has been completely redone from the ground up (for the most part). Without further chatter, let’s get into it.
People have reported in the past that the explanation for this part wasn’t clear at all, so I’m going to link another users tutorial who explained this entire Step 1 in way better detail than I did. In case you’re curious to see how I explained it, please expand the “(Old Post) Version 1” dropdown at the top of this post.
There is no point in reiterating what someone else has already said. Their tutorial is really good. Give it a read.
Turns out this entire system actually had support for multiple Motor6D’s on different body parts. You just need to create more Motor6D’s and add them to the Motor6DHandler script, more on that later.
Woohoo! You assembled your dummy for use, and can now create the script that actually allows you to use the Motor6D animation you created with @H_mzah’s tutorial!
At this point you should have something like this:
Now, you might be thinking, “Why is the tool in the center of the dummies Right Arm?” which is perfectly reasonable without explanation.
Motor6D's make another
BasePart that is assigned
Part1 use the position of whatever
BasePart is under
Part0. This won’t ruin your animation, in fact you can relocate the position of the tool when you’re animating. As I mentioned on the previous tutorial, I automatically assume you know how to properly animate and upload animations to Roblox if you’re following this tutorial. I won’t be teaching you how to animate, that’s out of the scope of this resource.
Go ahead and upload your animation when you’re finished with it, and put the ID of the Animation inside the
AnimationId” property field, or inside the script you’re
Instance.newing an animation with.
Once that is all out of the way, move onto Step 3.
Now that you have the animation uploaded, you want to get it to actually work. Well, how do we do that? With a script of course! Also don’t worry, we won’t be using any hacky methods or RemoteEvents inside of a LocalScript to achieve any of this. Looking at you @Headstackk Thank you for your tutorial though!
First, you want to get this model that I created and uploaded to the Roblox Website. I would paste source code, but you can insert it and read the code yourself. I don’t want to post any raw code here because if I do, and an issue arises, then I might forget to actually update the code here.
Motor6DHandler Model: GET IT HERE!
(Also don’t worry, if you’d like to know what each thing does in the script, I’ve left comments from the old script still in there with the fresh and updated code!)
(Updated Section as of 2021/10/20)
Script inside the
Tool of your choice. Make sure your tool has a
Handle or else the script will infinite yield, or error! Theoretically you can name the part that has to be named
Handle anything, but then you must disable the RequiresHandle property on your Tool, or else you might get unexpected results.
The script now comes installed with 2 script attributes for setting the:
- Name of the Body Part you want your tool to be attached to
- The name of the Tools Handle part that you want to be attached with your previously specified Body Part attribute.
The defaults Attributes are shown here, so it’s still a drag and drop solution for R6 avatars.
Now that you have the Animation ready, and the Motor6D installed as a Child of your tool, you will need to now load the animation onto the Players Character for it to actually work, because how else are you going to play an Animation on the Players Character?
If you’re new to loading animations, I will provide an example here for you to use:
Personally what I recommend doing is making a folder named “Animations” under the tool object, and store any animation you might need in that folder. Then you can reference it with another
Script that you use to load your animations. If you want, you can install your load animation script directly into the Motor6DHandler, but you might have to adjust some things for that to work, so I personally recommending using an entirely different script for loading animations.
Load Animation Mock-Up
-- Highly recommend making an Animations Folder under your tool, and referencing it here. -- local AnimationsFolder = script.Parent.Animations -- Once you put your animations inside the AnimationsFolder, you can reference them here. local Activate = AnimationsFolder.Activate local Idle = AnimationsFolder.Idle -- Make empty variables here with the name of your Animations so :LoadAnimation() can store memory in these later -- local ActivateAnimation local IdleAnimation -- debounce so people cannot spam your Activate animation (Animation that plays when you click, if you even need that.) -- local db = false -- Main Script -- script.Parent.Equipped:Connect(function() -- Assign the Empty Variables we defined outside the equip function so they can be globalized. (Used in all functions) ActivateAnimation = script.Parent.Parent.Humanoid:WaitForChild("Animator"):LoadAnimation(Activate) IdleAnimation = script.Parent.Parent.Humanoid:WaitForChild("Animator"):LoadAnimation(Idle) -- You need an idle animation for the tool so it doesn't go to the center of your Right Arm (or RightHand if you're using R15). IdleAnimation:Play() end) -- Animation that will play when you Click with the Tool Equipped -- script.Parent.Activated:Connect(function() if not db then db = true ActivateAnimation:Play() task.wait(1) -- Improved version of wait(). I highly recommend using this for any new work. end end) -- Animation that will be stopped upon unequipping your tool. -- script.Parent.Unequipped:Connect(function() ActivateAnimation:Stop() IdleAnimation:Stop() end)
Please keep in mind, you will need an Idle Animation to prevent the Tool from going to the center of the Right Arm or RightHand (depending on what RigType you use). This has been a known issue in the past, and the only way to fix it is to animate an Idle to make up for the fact that the RightArmGrip gets deleted.
For more information or more of a visual guide, please see this fellow users post: How to animate Tool Handles easily! (Specifically melees, unsure of guns) - #46 by TheSuzerain
In case you’re questioning why we need to delete the RightArmGrip inside the Right Arm, allow me to explain. It’s because the Tool will automatically void any Motor6D’s that get attached to the RightArm, which is really bad for us, because that means your animations won’t load properly, and if they do, they will bug out or stop working eventually.
Roblox hint hint
After you’re done creating your LoadAnimation script, and the Motor6D is inserted inside your tool, you can now go ahead and test it!
Yes, finally the fun part.
Upon testing, these are the results I get when following this tutorial:
If your animation doesn’t appear the way you animated, or doesn’t seem to play, make sure you double check these:
The Motor6DHandler script is exactly the way I wrote it. The only thing you should be changing is anything inside the script that says “Right Arm” to “RightHand” if you’re using the R15 RigType.
Check the console for any errors by pressing “Shift + F9” or “F9” on your keyboard while in Studio, or by typing “/console” in the Roblox Chat. If you see any errors regarding the Motor6DHandler or your script, please post here so I can assist the best I can.
- Your Idle Animation is set to AnimationPriority
Action, and your
Tool.Activatedfunction animation is set to
Action2upon exporting the Animation. Due to the new release of
WeightedAnimationBlendFix, it’s recommended to utilize these new extra Animation Priorities to make up for the unintended behavior that
WeightedAnimationBlendFixcauses. DO NOT TURN OFF THE
WeightedAnimationBlendFixTOGGLE BECAUSE IT WILL BE FORCED ON SOON! YOU SHOULD BE MIGRATING YOUR ANIMATION PRACTICES!
Thank you so much for reading this tutorial! I’m happy I was able to re-write it and correct most of the script mistakes I made in the last version of this post, and I hope this is an easy and updated way compared to the old method. The old post contained a method which used StarterCharacterScripts, but then it also recommended use of the Tool so it was confusing. Now this post only recommends putting the Motor6DHandler script inside your tool at all times for further compatibility reasons.
If yes, please contact me with a Developer Forum private DM. I re-wrote this post, and it’s been such a long time since I’ve read over this post. I might have left something critical out so I’m happy to further revise this post as necessary to accommodate other peoples needs, as long as it’s not out of the scope of this resource.
@H_mzah - How to animate a tool with a Dummy in Animation Editor
@Headstackk - Leading me up to this post, as well as making his solution for animating Handles.
@Duskitten - Telling me about RightGrip, and needing to delete it using the script I had created. Peer reviewing my script, and other help.
@friedraice - Helping me figure out that this procedure REQUIRES an idle animation for the handle, or else the tool will move to the center of the Right Arm