Particle on a Humanoid

I made a run animation and thought of adding a “Dust Trail” or have Particles on the characters feet. Is it as simple as just adding particle emitters through starter character? I’m new to scripting so you might have to explain some of it

7 Likes

I think this might help you, i hope this helps!

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Particles = ReplicatedStorage:FindFirstChild("Put your Particle name here") --Remember to put Your particle in ReplicatedStorage!

local Parts = script.Parent:GetChildren()

for _, Part in pairs(Parts) do
    if Part:IsA("BasePart") or Part:IsA("Part") or Part:IsA("MeshPart") then
        local ParticlesInChar = Particles:Clone()
        ParticlesInChar.Parent = Part
    end
end)
1 Like

Thank you! Where would I exactly put all of this stuff? Meaning where would I put the script or the “part”. Sorry but like before I’m not perfect at reading scripts.

1 Like

Put the script in StarterPlayer > StarterCharacterScripts, i think this would work.

1 Like

adsadsd

Here is what everything looks like. I tried using a local script because I didn’t know what kind of script and none of them worked

1 Like
local Particles = ReplicatedStorage:FindFirstChild("ParticleEmitter") --Remember to put Your particle in ReplicatedStorage!

Have you changed the Particle name? Also, there’s any error?

1 Like

Hey, i found the error! Here is the fixed script:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Particles = ReplicatedStorage:FindFirstChild("Put your Particle name here") --Remember to put Your particle in ReplicatedStorage!

local Parts = script.Parent:GetChildren()

for _, Part in pairs(Parts) do
    if Part:IsA("BasePart") or Part:IsA("Part") or Part:IsA("MeshPart") then
        local ParticlesInChar = Particles:Clone()
        ParticlesInChar.Parent = Part
    end
end

Try to read a bit in the Output and check the errors to fix :slight_smile:

2 Likes

Yeah before nothing was showing in the output idk why. Ill try this

What I would do would be relatively simple:

  1. Insert a BasePart using instance.new from either the Client or Server. If it is created by the Client, it won’t be seen by other players. If it is created by the Server, other players would see your dust particles.
  2. Use a RunService loop to keep this part at the desired position. I recommend a position around here for your BasePart: HumanoidRootPart.CFrame - Vector3.new(0,2,0).
  3. Create a Particle Emitter within the BasePart using Instance.new. Adjust the particle emitter to your liking.
  4. Now that you have your particles working, you will have to make sure that the particles only enable when the player is moving. Here is some code I found in EgoMoose’s Character Controller which returns if the player is moving or not:
function Module:isMoving()
	local moveSq = ClientHumanoid.MoveDirection:Dot(ClientHumanoid.MoveDirection);
	return moveSq > 0 and ClientHumanoidRootPart.Velocity.magnitude > 4;
end
  1. In a RunService loop, check if the player is moving. If the player is moving, enable the particle emitter:
if Module:isMoving() then
    ParticleEmitter.Enabled = true;
else
    ParticleEmitter.Enabled = false;
end
  1. (Optional) If you want to disable the dust particle while in the air, just add this to the code above:
if ClientHumanoid.FloorMaterial == Enum.Material.Air then
    ParticleEmitter.Enabled = false;
else
    if Module:isMoving() then
        ParticleEmitter.Enabled = true;
    else
        ParticleEmitter.Enabled = false;
    end
end

Hope this helps!

1 Like

This goes in StarterCharacterScripts correct?

I would execute it through a module in the replicated-storage (executed by the client), however, a local script in the StarterCharacterScripts / StarterPlayerScripts would potentially work. Don’t take my word for it!

1 Like

Honestly. I think that would be quite unecessary to do a RunService loop CFraming particles. And maybe this would hurt performance. The script i have provided works fine, i guess…


But i would like to talk with you through messages about how the code you provided works! I want to learn a bit :slight_smile:

1 Like

I tried your code and it does work! But I would like to have it at the feet and not the whole body

Oh, in this case, instead of checking if there are parts, baseparts and meshes, you can check if the part is named X, also, this works for R15 and R6, if you are asking me.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Particles = ReplicatedStorage:FindFirstChild("Put your Particle name here") --Remember to put Your particle in ReplicatedStorage!

local Parts = script.Parent:GetChildren()

for _, Part in pairs(Parts) do
    if  Part.Name == "LeftFoot" or Part.Name == "RightFoot" or Part.Name = "RightLeg" or Part.Name = "LeftLeg" then
        local ParticlesInChar = Particles:Clone()
        ParticlesInChar.Parent = Part
    end
end
2 Likes

Hi TriipXX, I see what you’re talking about. So you want to make particles come out the player’s feet when ever they step. Personally, I like the particles to come out each foot individually, so this is the way I did it, I’m pretty sure you can optimize this even more.

local hrp = Figure:WaitForChild("HumanoidRootPart")
local runningSound = Instance.new("Sound")
runningSound.Parent = hrp
runningSound.SoundId = "rbxassetid://481217914"
runningSound.Volume = 2

local rightAttach = Figure:WaitForChild("Right Leg"):WaitForChild("RightFootAttachment")
local leftAttach = Figure:WaitForChild("Left Leg"):WaitForChild("LeftFootAttachment")

local rightParticles = script:WaitForChild("Dust"):Clone()
rightParticles.Parent = rightAttach
local leftParticles = script:WaitForChild("Dust"):Clone()
leftParticles.Parent = leftAttach

For this to work, you first have to copy the “Animate” default script (which I’ve sure you’ve done) and put it in StarterCharacterScripts. Remember some of these things are already predefined for R6 models, but you might have to change some stuff around for R15. So this code block initializes the running sound. The rightAttach and leftAttach is default attachments instances on Roblox’s R6 character (this is where the particles will spawn), right below the foot. I almost made pre-made dirt particles that is a child of the Animate script. Make sure the particles Rate property is set to zero, as we want to control when the particles spawn.

image

Now in the animate script, there is already a built in function for when an “Keyframe is reached”. Basically, you can rename different keyframes in your animation to do different things. For this example, for my run animation, I named right when the player stepped on the ground’s keyframe “LeftStep”, and I did the same with the right.

Control + F in the Animate script and find function keyFrameReachedFunc(frameName)
This function automatically fires when a keyframed is reach in an animation, such as “LeftStep” and “RightStep” accordingly.

You want to put this inside the code:

if frameName == "LeftStep" then
	runningSound:Play()
	leftParticles:Emit(1)
elseif frameName == "RightStep" then
	runningSound:Play()
	rightParticles:Emit(1)
end

frameName is the current KeyFrame’s name. By default it’s named “KeyFrame” but assuming you changed the name or the keyframe with no spelling errors “LeftStep” and “RightStep” keyframes are in your animation.

Now, all there is left to do is test it!

As you can see it works beautifully!

12 Likes

Oh nice. Now does this only work for animated running animations?

Yes, it only works if you make a custom running animation and rename the Keyframes accordingly.

Oh cool. I’ll try this code in a little bit this seems like it works. Thank you for this I will let you know if it works or not. Also before I try this where do I put the first and second script? For the second do I put it below keyFrameReachedFun(frameName) or the same line its on? I want make sure this is right.

You put it inside the function. Again, if your rig is different you may need to rename some things in the script for it to work. For example the “Figure” variable might be renamed to “Character” on the R15 animate script or “Left Leg” will be “LeftFoot” on the R15 rig. Watch out for that.

1 Like

Ok, I’ll try it later thanks again! Sorry for the dumb questions I’m not so good at scripting or reading it.