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!
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
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)