Fastcast cosmetic bullet not showing if target is close

Hello! In the last hours i’ve tried to make work the cosmetic bullets of my third person shooter framework. The problem here is that the cosmetic bullet doesn’t show if the target if close, sometimes not even if there is enough distance.

Video:

Here is the code:

local function onCosmeticRayHit(castHandler, result, velocity, projectile)
	projectile.Anchored = true
	projectile.Position = result.Position
end
local function onCosmeticLengthChanged(cast, lastPoint, direction, length, velocity, bullet)
	if bullet then
		bullet.CFrame = CFrame.lookAt(lastPoint, lastPoint + direction):ToWorldSpace()
	end
end
function FastCastHandler:cosmeticFire(weaponCastProperties, originalChar, finalHitPos, originalDirection)
	local weaponModel = originalChar:FindFirstChild(weaponCastProperties.weaponName)
	local weaponMuzzle = weaponModel:FindFirstChild("RootPart"):FindFirstChild("Muzzle")
	
	local cosmeticOrigin = weaponMuzzle.WorldCFrame.Position
	local cosmeticFireDirection
	
	if finalHitPos then
		cosmeticFireDirection = (finalHitPos - cosmeticOrigin).Unit
	else
		cosmeticFireDirection = originalDirection.Unit
	end
	
	castParams.FilterDescendantsInstances = {originalChar, workspace.Bullets}
	
	cosmeticCastBehavior.Acceleration = Vector3.new(0, weaponCastProperties.gravity, 0)
	cosmeticCastBehavior.MaxDistance = weaponCastProperties.maxDistance
	cosmeticCastBehavior.CosmeticBulletTemplate = bulletTemplate
	cosmeticCastBehavior.CosmeticBulletContainer = workspace.Bullets
	
    -- Velocity is set to 2000 in the video.
	cosmeticCaster:Fire(cosmeticOrigin, cosmeticFireDirection, weaponCastProperties.velocity, cosmeticCastBehavior)
end

Please help as i don’t know what is going on here!

1 Like

It might just be moving so fast its not even visible long enough for one frame. You might be able to get away with making the cosmetic bullet slower when the target is close.

I cant do that as a cast cant detect when is close to hit a target (Please let me know if its possible cause i dont know how to do that), and i think that if i do that, i wont be getting the result i want

Maybe you can use a while loop to constantly check if a player is close also making sure it’s not the player itself

I had the same problem (and also your previous topic thanks for the solution for that as well) and my I believe the issue is due to it being a trail and the ray updates only fires once.

Trails need position change in 2 frames to display, my solution was to delay this and force a change when the ray is hit:

It’s dirty but it’ll work:

    local bulletFrameNumberDictionary = {} --Counts how many time the ray has updated
    local function rayUpdated(
        activateCaster,
        segmentOrigin,
        segmentDirection,
        length,
        segmentVelocity,
        bullet: BasePart
    )
        -- local BulletLength = bullet.Size.Z / 2 -- This is used to move the bullet to the right spot based on a CFrame offset
        --offset bullet rotation
        local goalCF
        if bulletFrameNumberDictionary[bullet] ~= nil then
             goalCF = CFrame.lookAt(segmentOrigin, segmentOrigin + segmentDirection)
            * CFrame.new(0, 0, -(length/2 - BulletLength))    
        else
            bulletFrameNumberDictionary[bullet] = 0
            goalCF = CFrame.lookAt(segmentOrigin, segmentOrigin + segmentDirection)   

            local trail = bullet:FindFirstChildWhichIsA("Trail")
            if trail then
                trail.Enabled = true
            end

        end

        bulletFrameNumberDictionary[bullet] += 1

        -- local lookCFrame = CFrame.lookAt(segmentOrigin, segmentOrigin + segmentDirection)
        -- debugPos(lookCFrame, BrickColor.Red())
        -- debugPos(goalCF, BrickColor.Blue())
        -- local currentPoint = segmentOrigin + (segmentDirection * length)
        -- debugPos(lookCFrame.Rotation + currentPoint, BrickColor.Yellow())

        -- print("ray update")
        -- print(bulletFrameNumberDictionary[bullet]," Bullet frame number")

        bullet:PivotTo(goalCF)
        -- bullet.CFrame = goalCF
        -- local trail = bullet:FindFirstChildWhichIsA("Trail")
    end

    local function cleanUpBullet(activeCast)
        local bullet = activeCast.RayInfo.CosmeticBulletObject

        -- task.spawn(function()
        --     task.wait(0.5) -- fixes the issue with point blank, means no trail bullet visible
        --     --Debris:AddItem(bullet,1)--normal instance.new clone
        --     local trail = bullet:FindFirstChildWhichIsA("Trail")
        --     if trail then
        --         trail.Enabled = false
        --     end
        --     bulletFrameNumberDictionary[bullet] = nil
        --     task.wait()
        --     projectileCache:ReturnPart(bullet)
        -- end)
        -- print("Cleanup")
        -- print(bulletFrameNumberDictionary[bullet]," Bullet frame number")
        if bulletFrameNumberDictionary[bullet] <= 2 then
            warn("First bullet! cleanup", bulletFrameNumberDictionary[bullet])
            task.wait()
            task.wait()
            task.wait()
        end
        print("Return bullet")

        local trail = bullet:FindFirstChildWhichIsA("Trail")
        if trail then
            trail.Enabled = false
        end
        bulletFrameNumberDictionary[bullet] = nil

        projectileCache:ReturnPart(bullet)

    end

    local function onRayHit(activeCast, result : RaycastResult, segmentVelocity, bullet)
        if bulletFrameNumberDictionary[bullet] <= 2 then
            warn("First bullet! HIT", bulletFrameNumberDictionary[bullet])
            local direction = result.Position - bullet.Position
            local originalPosition = bullet.Position
            task.wait()
            print("Move 1")
            bullet.CFrame = bullet.CFrame + direction*0.5
            task.wait()
            print("Move 2")
            bullet.CFrame = bullet.CFrame + direction*0.5
        end

    end


    caster.RayHit:Connect(onRayHit)

    caster.CastTerminating:Connect(cleanUpBullet)

    caster.LengthChanged:Connect(rayUpdated)

10 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.