Hello there, my friends of DevForum.
Today I would like to share something that I don’t think is even close to easy enough to find tutorials on.
By the end of this tutorial, you should know how to:
1: Import skinned meshes for use as custom characters
2: Animate them
3: Use them in-game
Without wasting any more time, let’s start.
STEP 1: IMPORTING THE CHARACTER
To use Avatar Importer, go into the plugins tab and select “Avatar Importer”
From there, select “Custom” and select the 3d model of your character. NOTE: For this method, your character MUST be a .fbx file.
Now that you have the character model in the workspace, follow these steps:
- Rename the “FBXImportGeneric” group to “StarterCharacter”.
- You can delete the “InitialPoses” folder.
- Replace the AnimationController with a Humanoid.
- Add a part called “HumanoidRootPart”. Turn CanCollide off and move it around the character. Also turn the transparency to 1.
Now your explorer should look like this: (I changed the name of the cube later as well)
STEP 2: CREATING MOTOR6D’S
First, you’ll need to install a plugin that can do this. I personally like to use this plugin, but there are others you can use, like RigEdit.
First, select the HumanoidRootPart.
Then, select your character.
Create a Motor6d between them. To do this with Constraint Editor, click “new Motor6d”
This should create a Motor6d parented to the HumanoidRootPart.
STEP 3: ANIMATING THE CHARACTER
Now that we have the Motor6d set up, we can animate our character.
In the plugins tab, select Animation Editor.
The animation editor will open, if you’ve done everything correctly, click on the character, and then create animation.
It should look something like this if you have your bones done correctly:
This isn’t a tutorial on how to animate, so I’ll fast-forward to after I’ve made the animation.
Publish the animation, and keep the ID somewhere for later.
STEP 4: APPLYING THE ANIMATIONS
In this tutorial, we’ll use a custom animate script because I couldn’t get Roblox’s default one to work.
Create a LocalScript called “Animate” inside of StarterCharacterScripts, and put this script inside of it:
repeat task.wait() until script:FindFirstChildWhichIsA("Animation")
local idleAnim = script.Parent.Humanoid:LoadAnimation(script.Idle)
idleAnim.Looped = true
idleAnim.Priority = Enum.AnimationPriority.Idle
local runAnim = script.Parent.Humanoid:LoadAnimation(script.Run)
runAnim.Looped = true
runAnim.Priority = Enum.AnimationPriority.Movement
local jumpAnim = script.Parent.Humanoid:LoadAnimation(script.Jump)
jumpAnim.Looped = true
jumpAnim.Priority = Enum.AnimationPriority.Movement
local climbAnim = script.Parent.Humanoid:LoadAnimation(script.Climb)
climbAnim.Looped = true
climbAnim.Priority = Enum.AnimationPriority.Movement
local fallAnim = script.Parent.Humanoid:LoadAnimation(script.Fall)
fallAnim.Looped = true
fallAnim.Priority = Enum.AnimationPriority.Movement
local swimAnim = script.Parent.Humanoid:LoadAnimation(script.Swim)
swimAnim.Looped = true
swimAnim.Priority = Enum.AnimationPriority.Movement
local sitAnim = script.Parent.Humanoid:LoadAnimation(script.Sit)
sitAnim.Looped = true
sitAnim.Priority = Enum.AnimationPriority.Movement
game["Run Service"].Heartbeat:Connect(function()
if script.Parent.HumanoidRootPart.Velocity.Magnitude > 0.1 then
if script.Parent.Humanoid:GetState() == Enum.HumanoidStateType.Dead then
for _, i in script.Parent.Humanoid:GetPlayingAnimationTracks() do
i:Stop()
end
elseif script.Parent.Humanoid:GetState() == Enum.HumanoidStateType.Seated then
if not sitAnim.IsPlaying then
sitAnim:Play()
end
elseif script.Parent.Humanoid:GetState() == Enum.HumanoidStateType.Jumping then
if not jumpAnim.IsPlaying then
jumpAnim:Play()
end
elseif script.Parent.Humanoid:GetState() == Enum.HumanoidStateType.Climbing then
if not climbAnim.IsPlaying then
climbAnim:Play()
end
elseif script.Parent.Humanoid:GetState() == Enum.HumanoidStateType.Freefall then
if not fallAnim.IsPlaying then
fallAnim:Play()
end
elseif script.Parent.Humanoid:GetState() == Enum.HumanoidStateType.Swimming then
if not swimAnim.IsPlaying then
swimAnim:Play()
end
elseif script.Parent.Humanoid:GetState() == Enum.HumanoidStateType.Running then
if not runAnim.IsPlaying then
runAnim:Play()
end
end
else
for _, i in script.Parent.Humanoid:GetPlayingAnimationTracks() do
if i.Name ~= "Idle" then
i:Stop()
end
end
if not idleAnim.IsPlaying then
idleAnim:Play()
end
end
end)
If you don’t have any of those animations, comment out anything that you don’t use.
It may also be better to switch the position of the elseif’s.
Under the LocalScript, add 7 animations and name them like this:
Put the ID of each animation you have into the animations accordingly.
And lastly, place your grouped character into StarterPlayer and everything should work!
Thank you for taking the time to read this tutorial. If you have any questions or critiques, feel free to leave a comment!
If something doesn’t work for you, also leave a comment. You can DM me about it too!