I have a map with some dust on the floor but i don't want it to be just a decoration. I want some particles to appear on peoples feet while they are walking and disappear while they are not walking. I used a script and a local one in the main script but they did not work well because they were coming out of the center of the body. I would appreciate any help. Main one:
game.Players.PlayerAdded:connect(function(player) player.CharacterAdded:connect(function(character) script.ParticleWalkLocal:Clone().Parent = character end) end)
Local Script:
local FORCE = 5 local UP_VELOCITY = 30 local GRAVITY = 5 local DURATION = 2 local VIEW_DISTANCE = 1000 local SIZE = 9 local INTERVAL = 0.05 local player = game.Players.LocalPlayer local character = player.Character local camera = Workspace.CurrentCamera local mouse = player:GetMouse() local particleContainer = Instance.new("ScreenGui", player.PlayerGui) particleContainer.Name = "ParticleContainer" local particles = {} local CreateParticle3D do local function PointToScreen(point) local f = mouse.ViewSizeY/2 / math.tan(math.rad(camera.FieldOfView/2)) local p = camera.CoordinateFrame:pointToObjectSpace(point) return UDim2.new(0, -p.X*f/p.Z + mouse.ViewSizeX/2, 0, p.Y*f/p.Z + mouse.ViewSizeY/2) end function CreateParticle3D(position, velocity, lifetime, color, width, specificGravity) local mGravity = (specificGravity or 9.81) * 20 local mGui = Instance.new("Frame", particleContainer) local mStartTime = tick() mGui.Size = UDim2.new(0, width, 0, width) mGui.Position = PointToScreen(position) - UDim2.new(0, width/2, 0, width/2) mGui.BorderSizePixel = 0 mGui.BackgroundColor3 = color or Color3.new(1, 0, 0) local self = { Position = position; Velocity = velocity; Transparency = 0; } local function IsVisible() local cameraPos = camera.CoordinateFrame.p local vec = self.Position-cameraPos if vec.magnitude >= VIEW_DISTANCE then return false end return not Workspace:FindPartOnRay(Ray.new(cameraPos, vec)) end function self:Update(dt) self.Velocity = self.Velocity + Vector3.new(0, -mGravity * dt, 0) self.Position = self.Position + self.Velocity * dt if lifetime > 0 and tick()-mStartTime >= lifetime then mGui:Destroy() for i = 1, #particles do if particles[i] == self then particles[i] = nil end end return end if IsVisible() then mGui.Visible = true mGui.Position = PointToScreen(self.Position) - UDim2.new(0, width/2, 0, width/2) else mGui.Visible = false end end mIndex = #particles + 1 self:Update(0) table.insert(particles, self) return self end Spawn(function() local elapsed while true do elapsed = wait() for index, particle in pairs(particles) do particle:Update(elapsed or 0.03) end end end) end while wait(INTERVAL) do local torso = character:FindFirstChild("Torso") CreateParticle3D( torso.Position, Vector3.new(math.random()*2-1, 0, math.random()*2-1).unit * FORCE + Vector3.new(0, math.random()*UP_VELOCITY, 0), 1, torso.Color, SIZE, GRAVITY ) end
I know this is a very late response, but I'm trying to go through the old unanswered questions.
I think in this case you're overthinking this a bit much. For one, you should use a particle emitter. For the purpose of this example I'm just going to use a fire particle I found in free models to create flame steps.
The second thing you're overthinking is how to get the position where you place the particles. It's actually really simple, raycast in intervals between each leg!
With all that in mind you can easily create a feet particle script.
local player = game.Players.LocalPlayer; local character = player.CharacterAdded:wait(); local hrp = character:WaitForChild("HumanoidRootPart"); local part = Instance.new("Part"); part.Size = Vector3.new(0.2, 0.2, 0.2); part.Transparency = 1; part.CanCollide = false; part.Anchored = true; script:WaitForChild("particle").Parent = part; -- put the particle in the part local left = true; while true do left = not left; local ray = Ray.new((hrp.CFrame * CFrame.new(left and 0.5 or -0.5, -1, 0)).p, Vector3.new(0, -2.5, 0)); local hit, pos, normal = game.Workspace:FindPartOnRay(ray, character); if hit then local temp = part:Clone(); temp.CFrame = CFrame.new(pos); temp.Parent = character; -- for easy raycast ignoring game:GetService("Debris"):AddItem(temp, 3); -- get rid of in 3 seconds end; wait(0.1); -- can change this for rate end;