How to properly generate lightning

Hello developers, today I’m in need of your assistance

To summarize, I’m trying to generate lightning. It will begin at a height of 500, and go to the ground (Y = 0). My method below starts with an un-rotated part at Y = 500, and subsequent parts are added from there until it touches the ground.

There are some obvious issues. For one, if each rotation happens to go the same direction, it could be extremely long, like the photo above. The second issue is that there are gaps between each part that I can’t determine how they appear (you can see them if you look closely). If you’d like to help me generate some lightning, please provide some assistance below! I’d appreciate it a lot, and it’ll be used in my next ATF game:D

The code above clones a neon part from storage (523), gives it a random length (524), CFrames it to the previous lightning part so its middle point is at the bottom of the previous part (525), rotates it a random way (526 - 527), and then CFrames it again so its top point is at the bottom point of the previous part (528).

5 Likes

Can’t you just clamp the maximum angle rotation? Like you could store the current rotation as a variable somewhere and make sure it’s not going above or below a certain amount, so it will not be so loopy and strange-looking.

3 Likes

You can generate the direction using polar coordinates, and if you do this in world space you will get a consistent overall direction since the height component is easy to control.

The following snippet generates this lightning:

local serv = game.ReplicatedStorage

function CastLightningDown(head) -- vector3 start position

	local maxRange = 5 -- how far in polar coordinates can the lightning go
	local heightOffset = 10 -- how far the 3D vector is offset
	
	local boltParts = {}

	while head.Y > 0 do -- the advantage of using a Vector3 as the end of the lightning bolt
		local angle = math.pi*4*math.random() -- 4 because I don't trust the random distribution
		local radius = math.random()*maxRange -- radius

		local dir = Vector3.new(math.cos(angle)*radius,-heightOffset,-math.sin(angle)*radius) -- converting the XY plane of a graph into the XZ plane of a part requires Z to be negative

		local newPart = serv.Lightning:Clone()
		newPart.Size = Vector3.new(2,2,math.random(8,40)) -- component change to take advantage of CFrame's 2-vector construction method
		newPart.CFrame = CFrame.new(head,head+dir)*CFrame.new(0,0,-newPart.Size.Z/2) -- starting point, target point, and offset by half the length
		table.insert(boltParts,newPart)
		head = newPart.CFrame*Vector3.new(0,0,-newPart.Size.Z/2) -- move the head to the end of the part so we can continuously cast bolts
	end
	for _,part in ipairs (boltParts) do
		part.Parent = workspace
	end
end

for i = 1, 30 do -- make 30 lightning bolts
	CastLightningDown(Vector3.new(math.random(-200,200),math.random(100,300),math.random(-200,200)))
end

You can make the lightning straighter by decreasing maxRange of increasing heightOffset, and you can make the lightning more crooked by increasing maxRange or decreasing heightOffset.

If you want to make the lightning strike a particular place, I recommend generating the lightning from bottom to top instead. All you would have to do is make heightOffset positive and change the while loop condition.

12 Likes

Hey there,

I made a lightning library a while ago that I think you will find useful. You can give it two Vector3s, a start and an end point, and then several options to customize it to get it to look just how you want. The documentation can be found on the GitHub repository.

You can find it here: https://github.com/evaera/EvLightning

Or as a Roblox model here: https://www.roblox.com/library/386839042/EvLightning-v1-2-1

30 Likes

I think @buildthomas was working on a lightning library as well, but I don’t ever remember if he released it.

1 Like

https://devforum.roblox.com/t/procedural-lightning/15787

Start with a straight line between the origin and the target. Split it in half and offset the midpoint. Now you have two line segments. Split those in half and offset the midpoint. Repeat a few times until you have lightning.

12 Likes

can you please explain the code and how could I point it to land on a player

The post you replied to is three years old and the guy who posted it hasn’t been online for almost a year. His code can’t be used for targeting anything as it just travels in a random direction.

This is a safe free model made by Roblox with the code you are looking for. It won’t look nearly as nice, but hopefully you can learn from it in time. Currently I wager it is a bit above your skill level (if you were properly ready for this type of math, you likely wouldn’t need it explained) and it would take a lot of effort to explain it all, but I’m sure you can use it just the same. Good luck with it!

1 Like