How do I simulate bullet drop? I'm not using body movers

  1. What do you want to achieve? Keep it simple and clear!
    I want to simulate bullet drop for projectiles in my game. I don’t use body movers. I use frame manipulation to move the bullet and raycast ahead of the bullet to detect hits.
-- my projectile movement code. (this is in a local script in startercharacter.)
local connection
	connection = run.RenderStepped:Connect(function(dt)
		bullet.CFrame *= CFrame.new(0, 0, -weaponData.BulletVelocity * dt * 60)
		if (bullet.Position - firePos).Magnitude > 3000 then
			connection:Disconnect()
			bullet:Destroy()
		end
		local hit = workspace:Raycast(bullet.Position, bullet.CFrame.LookVector * weaponData.BulletVelocity, raycastParams)
		local hit2 =  workspace:Raycast(bullet.Position, bullet.CFrame.LookVector * -weaponData.BulletVelocity, raycastParams)
		if hit or hit2 then
			Evt.Hit:FireServer((hit and hit.Instance) or hit2.Instance or nil, weaponData)
			connection:Disconnect()
			bullet:Destroy()
		end
	end)```
1 Like

this is my first post here, so im not so familiar with how to use with maximum efficiency

1 Like

You could angle the bullet downwards very slightly every frame/step, while also moving it towards the new direction it is facing.
Unfortunately I’m not good with the code regarding this - I just know how it works.

Also, why not use purely raycasts?

I’m gonna try that, but how do I calculate the angle to tilt? Also I don’t use purely raycasts because I want to show that the bullet is travelling.

1 Like

im gonna try subtracting gravity from the bullet velocity

1 Like

that didn’t work out for me. im gonna try @Solar_Eos method.

Building on @Solar_Eos suggestion, you can use cframe:Lerp() to do this by adjusting the destination slightly. You just need to calculate it from the part’s new lookvector each time.

will try
Roblox character limit.exe yes


this is what happens after I fire

local connection
	connection = run.RenderStepped:Connect(function(dt)
		local bulletVelocity = Vector3.new(0, 0, -weaponData.BulletVelocity * dt * 60)
		bullet.CFrame *= CFrame.new(bulletVelocity)
		bullet.CFrame *= bullet.CFrame:Lerp(CFrame.lookAt(bullet.Position, bullet.CFrame.LookVector - Vector3.new(0, -10, 0)), 0.1).Rotation
		if (bullet.Position - firePos).Magnitude > 3000 then
			connection:Disconnect()
			bullet:Destroy()
		end
		local hit = workspace:Raycast(bullet.Position, bullet.CFrame.LookVector * weaponData.BulletVelocity, raycastParams)
		local hit2 =  workspace:Raycast(bullet.Position, bullet.CFrame.LookVector * -weaponData.BulletVelocity, raycastParams)
		if hit or hit2 then
			Evt.Hit:FireServer((hit and hit.Instance) or hit2.Instance or nil, weaponData)
			connection:Disconnect()
			bullet:Destroy()
		end
	end)

this is the current code

im not sure if my implementation is right or not tho, so please review.

I think this needs to just be " = " (not " *= ") because it has already taken the bullet.cframe to calculate the new cframe when you called the Lerp method.
(Hope that makes sense)

I implemented the changes but now the bullet won’t even move forward. it just stays there

I think its mostly because I keep setting bullet velocity to be the same.

I did have something similar working, but don’t have access to it right now, sorry.
Try changing the line to this one:

bullet.CFrame = bullet.CFrame:Lerp(bullet.Position + bullet.CFrame.LookVector - Vector3.new(0, -10, 0)), 1)

You should be able to control the distance travelled via the alpha, or a multiplier on the lookvector.

1 Like

it may or may not be my imagination, but I think I solved the problem

Have a downwards velocity set to the bullet, and because gravity is an acceleration, add gravity * deltaTime whenever you update the bullet position (if I’m remembering my physics right). You can cap it at whatever if you want a terminal velocity. Then I’d just make it look at wherever it’s projected to go before moving it, I dunno if one update behind on the lookVector is that huge of an issue

1 Like

thats what I did. lemme show the code for you guys so that you can see the changes.

local bulletVelocity
	
	run.Heartbeat:Wait()
	local connection
	connection = run.RenderStepped:Connect(function(dt)
		if not bulletVelocity then
			bulletVelocity = Vector3.new(0, 0, -weaponData.BulletVelocity * dt * 60)
		end
		bulletVelocity += Vector3.new(0, -workspace.Gravity * dt/1000, 0)
		bullet.CFrame *= CFrame.new(bulletVelocity)
		if (bullet.Position - firePos).Magnitude > 3000 then
			connection:Disconnect()
			bullet:Destroy()
		end
		local hit = workspace:Raycast(bullet.Position, bullet.CFrame.LookVector * weaponData.BulletVelocity, raycastParams)
		local hit2 =  workspace:Raycast(bullet.Position, bullet.CFrame.LookVector * -weaponData.BulletVelocity, raycastParams)
		if hit or hit2 then
			Evt.Hit:FireServer((hit and hit.Instance) or hit2.Instance or nil, weaponData)
			connection:Disconnect()
			bullet:Destroy()
		end
	end)
2 Likes

here I declared the bulletvelocity separately and then added a check and did the usual stuff. Thanks to all of you for your insight and help!

altho now I have to increase bullet velocity