Hey together!
I came across this question
and wanted to try that out. It started out simple but I spent so much time into researching ideas (I am an absolute beginner) etc. that I decided to make this an own topic and release it - and I couldn’t find ANYONE who posted this, so hopefully one of you may find it helpful. For the dust particle I used this https://create.roblox.com/store/asset/14448568026/Dust-effect dust effect. To be honest, I don’t know how much or if anything I changed on that effect (my settings are posted below), but I don’t want to just rip it off so download it there and use it on your own.
Demo:
You will need:
- A helicoper part or model
- A child in that folder named “HeliEffectPart” and which is a part. For that I used a simple flat cube. I then made it invisible. This part will emit the dust later on. Important: Unanchor and disable canCollide etc. for the part or else it will disturb gameplay.
- A child under “HeliEffectPart” which is the Dust and it has to be actually named “Dust”, it is a ParticleEmitter and I have the following settings for it:
- A child under “HeliEffectPart” which is the Dust and it has to be actually named “Dust”, it is a ParticleEmitter and I have the following settings for it:
- A child in that folder named “HeliEffectPart” and which is a part. For that I used a simple flat cube. I then made it invisible. This part will emit the dust later on. Important: Unanchor and disable canCollide etc. for the part or else it will disturb gameplay.
I put everything into worldspace.
Now place a script named “Heli” (name does not matter) under the helicopter part/model (same folder than HeliEffectPart). Magic Code:
local RunService = game:GetService("RunService")
local heli = script.Parent -- The helicoper part or heli model, in my case it's just a part, a flat cube
local heliPosition = nil -- DO NOT CHANGE THIS
local lastPosition = heli.Position
local heliEffectPart = heli:WaitForChild("HeliEffectPart") -- The effect part, in my case a copy of the heli part and transparency set to 1
heliEffectPart:WaitForChild("Dust")
local distance = 0
local minEffectSize = 8 -- Minimum effect size of the dust effect
local maxEffectSize = 40 -- Maximum effect size
local effectSizeMultiplier = 1.7 -- Overrides maxEffectSize, play around to make effect bigger, should always be >= 1 !
local effectOpacityMultiplier = 1 -- Makes effect more "aggressive", should always be >= 1 ! Best used with decimals as max. Opacity is anyways 1
local maxDistance = 40 -- Max distance from heli to floor to show effect. If heli above, no effect
local function updateDustEffect()
heliPosition = heli.Position
-- Only update if heli actually moved, this is also why lastPosition has to be nil initially
if lastPosition ~= heliPosition then
local direction = Vector3.new(0, -100, 0) -- scanning downwards
-- Since we have a HeliEffect part, we have to ignore that...
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {script.Parent}
raycastParams.FilterType = Enum.RaycastFilterType.Exclude -- ... by excluding children of the Heli script
local result = workspace:Raycast(heliPosition, direction, raycastParams)
-- If there is a hit
if result then
distance = result.Distance
else
distance = nil -- Set distance to nil if nothing was found, i.e. heli is too high or nothing below heli
end
-- Make sure distance is set and meets all requirements
-- Adding the 0 just to make sure
if distance and distance >= 0 and distance <= maxDistance then
print("helipos: " .. tostring(heliPosition) .. " vs direction " .. tostring(direction) .. " vs distance " .. result.Distance)
heliEffectPart.Position = result.Position -- This is moving the part of the effect which emits the dust
local heliEffectPartPosition = heliEffectPart.Position
-- Calculates effect size based on given parameters
local size = (maxEffectSize * maxDistance - maxEffectSize * distance) / maxEffectSize * effectSizeMultiplier
if size >= minEffectSize then
print("Size: " .. size)
-- Apply the scale to the part's Size
heliEffectPart.Size = Vector3.new(size, 1, size)
local sizeSequence = NumberSequence.new({
NumberSequenceKeypoint.new(0, size / 3), -- At 0 seconds, size is size / 3
NumberSequenceKeypoint.new(1, size) -- At 1 second, size is size
})
heliEffectPart.Dust.Size = sizeSequence
if not heliEffectPart.Dust.Enabled then
-- effect was disabled, enable it
heliEffectPart.Dust.Enabled = true
end
else
-- disable effect as effect size too low
heliEffectPart.Dust.Enabled = false
end
-- Heli too high
else
heliEffectPart.Dust.Enabled = false
end
lastPosition = heliPosition
end
end
RunService.Heartbeat:Connect(updateDustEffect)
- The effects are only working on one cube, the HeliEffectPart. If you hover over other parts, it will abruptly be stopped and new particles emitted on that other part (as can be seen in the demo, hopefully). This maybe can be fixed by a Tween (I don’t know, never worked with it yet) and by having multiple smaller HeliEffectParts that emit in different directions (e.g. in front left, front right, back etc. of the heli)
- Does not contain a heli
- Was not tested with a heli yet
- Is not optimal, I have no idea if it will lag or whatever
- Calculation examples were my own ideas, I played around a bit, but therefore they may be suboptimal
All it does so far is emit dust-like particles on the “floor”. When the “heli” gets closer to the ground, the particles get bigger (and the HeliEffectPart grows, spreading more particles). This is for testing purposes so you can play around (and to answer the intial question of the OP). Also, I constantly changed the code to make it look better, initially it was just a smoke effect but now that I look at it I actually like it a little bit
I found this an interesting experiment. Have fun with it and let me know if that helped you!