How would i add bullet drop to this Ray?

So the title says it all basically lol,
An example of how the gun works right now


i Want the bullets(Ray cast) to do this instead

local origin = Tool.GunTip.Position
				local direction = (MousePos - origin).Unit
				
				local RayCastParams = RaycastParams.new()
				RayCastParams.FilterDescendantsInstances = Player.Character:GetDescendants()
				RayCastParams.FilterType = Enum.RaycastFilterType.Blacklist
				
				local result = workspace:Raycast(Tool.GunTip.Position, direction* 300, RayCastParams)
				if result then
					local BulletHole = game.ServerStorage.ServerAssets.BulletHole:Clone()
					BulletHole.Parent = workspace
					BulletHole.Position = result.Position
					BulletHole.CFrame = CFrame.lookAt(result.Position, result.Position + result.Normal)
					
					
					local Weld = Instance.new("WeldConstraint")
					Weld.Part0 = BulletHole
					Weld.Part1 = result.Instance
					Weld.Parent = BulletHole
					
					Debris:AddItem(BulletHole, 10)
1 Like

There is some math you’ll need to do this. Lucky, someone did it for you!


Basically, gravity is a type of acceleration. So you’ll add some downwards acceleration per every second. You can integrate that to get this equation:

change in x = initial velocity * time + 0.5 * acceleration * time * time

You can just loop through doing raycasts until it hits something or hits a predefined limit (number of raycasts, distance, etc).

I dont really like open sourced modules lol, i wanna have all my scripts, local scripts to be owned by be

2 Likes

You can copy the source code. FastCast is used by hundreds of games (one of the most used modules on the forums probably).

You can also use that equation I posted every heartbeat (or with no delays for something hitscan-like).

Here’s a really simple version that you can work from:


-- Bullet ModuleScript
local RunS = game:GetService("RunService")

local MAX_LIFETIME = 5 --seconds
local GRAVITY = Vector3.new(0, -game.Workspace.Gravity, 0) --studs/second^2
local HIT_DETECT_RAYCAST_PARAMS = RaycastParams.new() --Set this up how you want it

function newBullet(startPosition, startVelocity)
    local onHitEventObject = Instance.new("BindableEvent")
    local onTimeoutEventObject = Instance.new("BindableEvent")
    local bullet = {
        position = startPosition, 
        velocity = startVelocity,
        onHit = onHitEventObject,
        onTimeout = onTimeoutEventObject,
        lifeTime = 0,
    }
    bullet.updateConnection = RunS.Heartbeat:Connect(function(dt) 
        updateBullet(bullet, dt) 
    end)
    return bullet
end

function updateBullet(bullet, dt)
    --Move the bullet along the parabola
    local oldPosition = bullet.position
    local newPosition = oldPosition + bullet.velocity * dt + GRAVITY * dt * dt

    bullet.position = newPosition
    bullet.velocity = bullet.velocity + GRAVITY * dt

    --Check if the bullet hit something
    local hitResult = hitDetect(oldPosition, newPosition)
    if hitResult then
        bullet.onHitEventObject.Event:Fire(hitResult)
        destroyBullet(bullet)
        return
    end
        
    --Destroy the bullet if it doesn't hit anything
    bullet.lifeTime += dt

    if (bullet.lifeTime > MAX_LIFETIME) then
        destroyBullet(bullet)
    end
end

function hitDetect(pointFrom, pointTo)
    return game.Workspace:Raycast(pointFrom, pointTo - pointFrom, HIT_DETECT_RAYCAST_PARAMS)
end

function destroyBullet(bullet)
    --Removed references to allow garbage collection
    bullet.onHit:Destroy() --Allows BindableEvent to be GC'ed, and breaks any connections to it
    bullet.onTimeout:Destroy() --Same
    bullet.updateConnection:Disconnect()
end

return {
    newBullet = newBullet,
}

-- Gun controller script
local BULLET_SPEED = 100 --studs/second

function shootGun(muzzleCFrame, bulletVelocity)
    local bullet = newBullet(muzzleCFrame.Position, muzzleCFrame.LookVector * BULLET_SPEED)
    bullet.onHit.Event:Connect(function(hitResult)
        local character = hitResult.Instance.Parent
        local humanoid = character:FindFirstChildWhichIsA("Humanoid")
        if humanoid then
            humanoid.Health -= 50
        end
    end)
end

Here’s an illustration explaining the math/physics:

16 Likes