zynon

procedural clouds (roblox lua)

Sep 2nd, 2022
2,323
0
Never
3
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.51 KB | None | 0 0
  1. --//minecraft-style perlin noise based cloud generation written 9/1/22 by zynonical
  2.  
  3. --settings
  4. local size = 300--the size of each individual cloud part, in studs
  5. local height = 500--the height of the cloud model, in studs on the Y axis. global.\
  6. local cloudspeed = 25--the speed that each cloudmodel moves. studs per second.
  7. local chunklength = 25--the square root of the number of clouds parts in a cloud model
  8. -----------------------------------------------------------------------------------------------
  9.  
  10. --
  11. local tweenservice = game:GetService("TweenService")
  12. local cloudfolder = Instance.new("Folder",workspace);cloudfolder.Name = "cloudfolder"
  13. --
  14.  
  15. local track = 0
  16. local function noise()
  17.     track = math.noise(track,0,math.random(2,999)/1000);return track --returns the noise, track is to keep track of the... noise.
  18. end
  19.  
  20. local function get_tween(model,speed,distance) --i find it cleaner and less repetitive to have the tweening done from a function. tweening system could really be improved by roblox
  21.     local info = TweenInfo.new((distance)/speed,Enum.EasingStyle.Linear,Enum.EasingDirection.In,0,false,0)--distance divided by speed == time
  22.     return tweenservice:Create(model.PrimaryPart,info,{CFrame = CFrame.new(Vector3.new(model.PrimaryPart.Position.X + (distance),height,model.PrimaryPart.Position.Z))})
  23. end
  24.  
  25. local function createcloudchunk() --generates the cloud chunk
  26.     local chunkmodel = Instance.new("Model")
  27.     local root = Instance.new("Part",chunkmodel) --root is for tweening the model.
  28.    
  29.     for i = 1, chunklength do --rows
  30.         if noise() <= -0.2 then
  31.             local newpart = Instance.new("Part",chunkmodel)-- chunkmodel.Parent is still nil, so the second parameter of Instance.new() is comepletely fine to use
  32.             newpart.Material = Enum.Material.SmoothPlastic;newpart.CanCollide = false;newpart.Anchored = false
  33.             newpart.Size = Vector3.new(size,25,size);newpart.Color = Color3.fromRGB(230,230,230)
  34.             newpart.Position = Vector3.new(0,height,i*size)
  35.             local weld = Instance.new("WeldConstraint");weld.Part0=newpart;weld.Part1=root;weld.Parent=newpart
  36.         end
  37.         for x = 1, chunklength-1 do --columns. --for each cloudpart in the bottom row, create #chunklength-1 number reaching out on the X-axis. results in grid.
  38.             if noise() <= -0.2 then
  39.                 local bpart = Instance.new("Part",chunkmodel)
  40.                 bpart.Material = Enum.Material.SmoothPlastic;bpart.CanCollide = false;bpart.Anchored = false
  41.                 bpart.Size = Vector3.new(size,25,size);bpart.Color = Color3.fromRGB(230,230,230)
  42.                 bpart.Position = Vector3.new(x*size,height,i*size)
  43.                 local weld = Instance.new("WeldConstraint");weld.Part0=bpart;weld.Part1=root;weld.Parent=bpart
  44.             end
  45.         end
  46.     end
  47.    
  48.     root.CFrame = chunkmodel:GetBoundingBox();root.Anchored = true;root.Transparency = 1--before i found out about :GetBoundingBox(), there was some really impressive math here
  49.     chunkmodel.PrimaryPart = root;return chunkmodel
  50. end
  51.  
  52. -----------------------------------------LOOP_FUNCTIONS
  53.  
  54. local function cloud()
  55.    
  56.     local e = tick();local chunk1 = createcloudchunk();print(tick()-e) --tick() for testing how fast the cloudchunk generation runs. ~0.0007 seconds is average. pretty good
  57.     --local chunk1 = createcloudchunk() --easily comment in/out to switch from printing tick() in previous line.
  58.    
  59.     chunk1:PivotTo(CFrame.new(Vector3.new(-(chunklength*size),height,0)))
  60.  
  61.     chunk1.Parent = cloudfolder
  62.    
  63.     local tween = get_tween(chunk1,cloudspeed,chunklength*size);tween:Play()
  64.     local listener; listener = tween.Completed:Connect(function() --these listeners all disconnect, so there's no concern for memory leaks
  65.         listener:Disconnect()
  66.  
  67.         local tween2 = get_tween(chunk1,cloudspeed,(chunklength*size)*2);tween2:Play();cloud()
  68.  
  69.         local listener2; listener2 = tween2.Completed:Connect(function()
  70.             listener2:Disconnect()
  71.             chunk1:Destroy()
  72.         end)
  73.     end)
  74. end
  75.  
  76. -----------------------------------------
  77. ------start
  78. local startingcloud = createcloudchunk()--this is kind of a cheat of my own code, but it's easier than rewriting the createcloudchunk() function. and this obviously only runs once
  79. startingcloud:PivotTo(CFrame.new(Vector3.new(0,height,0)))
  80. startingcloud.Parent = cloudfolder
  81. local tween = get_tween(startingcloud,cloudspeed,chunklength*size);tween:Play()
  82. local listen;listen = tween.Completed:Connect(function()
  83.     listen:Disconnect();startingcloud:Destroy()
  84. end)
  85. cloud()
  86. ------
  87.  
  88. --[[
  89.  
  90. super performant and easily customizable. 0.0007 seconds to generate a cloudchunk/model. runs great on even the lowest end mobile phones, and looks beautiful on lvl10 graphics (imo)
  91.  
  92. ]]
Advertisement
Comments
Add Comment
Please, Sign In to add comment