Alternatives for Fastcast?

Hello! I finished making a grenade throwing system but its not really satisfied. Heres the video

In this video I noticed that the fast cast is very choppy and it usually glitches through walls. Heres the fastcast code.

local gun = game.Lighting:WaitForChild("Weapons"):FindFirstChild("Flashbang"):Clone()
--local viewmodeldata = game.Lighting:WaitForChild("ViewModel"):FindFirstChild(gun.Name)
gun.Parent = script.Parent
local plr = script:FindFirstAncestorOfClass("Player")
local char = plr.Character or plr.CharacterAdded:Wait()
local weld = Instance.new("Motor6D")
weld.Parent = script.Parent
weld.Part0 = char.RightHand
weld.Part1 = gun.PrimaryPart

local anim = {
	Hold = nil


}

local gunspartthatisvisible = {}
for i,v in pairs(gun:GetDescendants()) do
	if v:IsA("BasePart") and  v.Transparency > 0 then
		table.insert(gunspartthatisvisible,v)
	end
end

--script.Parent.GunModelCharacter.Value = gun


script.Parent.Equipped:Connect(function()
	local humanoid = script.Parent.Parent:FindFirstChildOfClass("Humanoid")
	gun.Parent = script.Parent.Parent.PrimaryPart
	gun:SetPrimaryPartCFrame(char.RightHand.CFrame)
	if anim.Hold == nil then
		anim.Hold = humanoid:LoadAnimation(gun.Anim.Hold)
	end
	anim.Hold:Play()
end)
script.Parent.Unequipped:Connect(function()
	gun.Parent = nil
	anim.Hold:Stop()
end)

function shoot(pos)

	local dir = ((pos + Vector3.new(math.random(-2,2)/10, math.random(-2,2)/10, math.random(-2,2)/10)) - gun.Flame.Position).Unit * (pos - gun.Flame.Position).Magnitude
	local origin = gun.Flame.Position
	local midpoint = origin + (dir / 2)
	local bullet = Instance.new("Part")
	bullet.BrickColor = BrickColor.new("New Yeller")
	bullet.Material = "Neon"
	bullet.Anchored = true
	bullet.CFrame = CFrame.new(midpoint, origin)
	bullet.Size = Vector3.new(0.05, 0.05, (pos - gun.Flame.Position).Magnitude)
	bullet.Parent = game.Workspace:WaitForChild("IgnoreFolder")
	bullet.CanCollide = false
	bullet.CanQuery = false
	bullet.Transparency = 0.7
	game.Debris:AddItem(bullet, 0.06)
end
local FastCast = require(game.ReplicatedStorage:WaitForChild("FastCastRedux"))
local caster = FastCast.new()
caster.VisualizeCasts = true

local castParams = RaycastParams.new()
castParams.FilterType = Enum.RaycastFilterType.Blacklist
castParams.IgnoreWater = true
castParams.FilterDescendantsInstances = {char}


local casthit = 1
function CanRayPierce(cast, rayResult, segmentVelocity)

	-- Let's keep track of how many times we've hit something.
	casthit += 1

	-- And if the hit count is over 3, don't allow piercing and instead stop the ray.
	if (casthit > 3) then
		return false
	end

	-- Now if we make it here, we want our ray to continue.
	-- This is extra important! If a bullet bounces off of something, maybe we want it to do damage too!
	-- So let's implement that.
	--[[
		local hitPart = rayResult.Instance
	if hitPart ~= nil and hitPart.Parent ~= nil then
		local humanoid = hitPart.Parent:FindFirstChildOfClass("Humanoid")
		if humanoid then
			humanoid:TakeDamage(10) -- Damage.
		end
	end
	--]]

	-- And then lastly, return true to tell FC to continue simulating.
	return true

	--[[
	-- This function shows off the piercing feature literally. Pass this function as the last argument (after bulletAcceleration) and it will run this every time the ray runs into an object.
	
	-- Do note that if you want this to work properly, you will need to edit the OnRayPierced event handler below so that it doesn't bounce.
	
	if material == Enum.Material.Plastic or material == Enum.Material.Ice or material == Enum.Material.Glass or material == Enum.Material.SmoothPlastic then
		-- Hit glass, plastic, or ice...
		if hitPart.Transparency >= 0.5 then
			-- And it's >= half transparent...
			return true -- Yes! We can pierce.
		end
	end
	return false
	--]]
end
local enough = true
function returnstrue()
	return enough
end
local function Reflect(surfaceNormal, bulletNormal)
	return bulletNormal - (2 * bulletNormal:Dot(surfaceNormal) * surfaceNormal)
end
function castpierce(raypiercedcast, raycastResult, segmentVelocity, cosmeticBulletObject)
	local position = raycastResult.Position
	local normal = raycastResult.Normal

	local newNormal = Reflect(normal, segmentVelocity.Unit)
	caster:SetVelocity(newNormal * segmentVelocity.Magnitude)
end

local castBehavior = FastCast.newBehavior()
castBehavior.RaycastParams = castParams
castBehavior.Acceleration = Vector3.new(0, -workspace.Gravity, 0)
castBehavior.AutoIgnoreContainer = false
castBehavior.CosmeticBulletContainer = game.Workspace.IgnoreFolder
castBehavior.CosmeticBulletTemplate = game.Lighting:WaitForChild("RandomPart")
castBehavior.CanPierceFunction = returnstrue

local flashbang
local function onLengthChanged(cast, lastPoint, direction, length, velocity, bullet)
	if bullet and enough == true and flashbang then 
		local bulletLength = bullet.Size.Z/2
		local offset = CFrame.new(0, 0, -(length - bulletLength))
		bullet.CFrame = CFrame.lookAt(lastPoint, lastPoint + direction):ToWorldSpace(offset)
		flashbang:SetPrimaryPartCFrame(bullet.CFrame)
	end
end


local function onRayHit(cast, result, velocity, bullet)
	local hit = result.Instance
	--caster:Fire(cframe.Position+cframe.LookVector*1.4,cframe.LookVector,100,castBehavior)
	local character = hit:FindFirstAncestorWhichIsA("Model")
	if character and character:FindFirstChild("Humanoid") then
		character.Humanoid:TakeDamage(50)
	end

	game:GetService("Debris"):AddItem(bullet, 2)
end




function OnRayPierced(cast, raycastResult, segmentVelocity, cosmeticBulletObject)
	-- You can do some really unique stuff with pierce behavior - In reality, pierce is just the module's way of asking "Do I keep the bullet going, or do I stop it here?"
	-- You can make use of this unique behavior in a manner like this, for instance, which causes bullets to be bouncy.
	local position = raycastResult.Position
	local normal = raycastResult.Normal

	local newNormal = Reflect(normal, segmentVelocity.Unit)
	--cast:SetVelocity(Vector3.new(0,0,0))
	local vectors = newNormal * segmentVelocity.Magnitude
	local percen = 0.8
	print(vectors.Magnitude)
	if vectors.Magnitude > 3 then
		cast:SetVelocity(vectors * Vector3.new(percen,percen,percen))
	else

		enough = false
		flashbang.PrimaryPart.Anchored = true
		--Instance.new("Highlight",cosmeticBulletObject)
		--print(cosmeticBulletObject.Parent)
		--print("omg")
		--cast:SetPosition(cosmeticBulletObject.Position)
		cosmeticBulletObject.Anchored = true
		cosmeticBulletObject.CanCollide = true
	end

	-- It's super important that we set the cast's position to the ray hit position. Remember: When a pierce is successful, it increments the ray forward by one increment.
	-- If we don't do this, it'll actually start the bounce effect one segment *after* it continues through the object, which for thin walls, can cause the bullet to almost get stuck in the wall.
	cast:SetPosition(position)

	-- Generally speaking, if you plan to do any velocity modifications to the bullet at all, you should use the line above to reset the position to where it was when the pierce was registered.
end



script.Parent.ACS_Modulo.Variaveis.Throw.OnServerEvent:Connect(function(player,cframe)
	enough = true
	flashbang = game.Lighting:WaitForChild("Projectile").Flashbang:Clone()
	flashbang.Parent = game.Workspace.IgnoreFolder
	caster:Fire(cframe.Position+cframe.LookVector*1.4,cframe.LookVector,100,castBehavior)
	--local flashbang = game.Lighting:WaitForChild("Weapons").Flashbang:Clone()
	--flashbang.Parent = game.Workspace.IgnoreFolder
	--flashbang:SetPrimaryPartCFrame(cframe + cframe.LookVector*1.3 )
	--flashbang.PrimaryPart.Velocity = cframe.LookVector * 200
	--local dir 
end)
caster.RayPierced:Connect(OnRayPierced)
caster.LengthChanged:Connect(onLengthChanged)

The projectiles of the flashbang are just flashbang model but with scripted timeline (explosion effect) and the randompart object is just a hitbox. Its a 2,3,2 size and the way I do it. I just set the flashbangmodel to the hitbox cframe and when its velocity reaches near 0 it will stop the script.

I feel like im very unsatisfied with the result because it keeps glitching and it looks very choppy so i want to find an alternative ways. Im waiting to hear you guys solution! Thanks!

2 Likes

You can use quadratic function to achieve same effect as fastcast, see fastcast works this way:

  • Create Parabola and everytime new point appears raycast to it to see if we hit something
  • Apart of this, lerp part between those points but with very low frame rate soo it will look like bullet drop
  • Then after X time stop (ANTI-LAG)
  • If it hit something, then also stop and give result to script
  • Send info to the server and check if hit can be correct

Raycasts usually are done on client, soo you don’t need to worry about visuals and raycasts being desynced

EDIT: Also you can simply create bounding box without part, i’m sure you can give position, CFrame and size and it will create one, also you can simply compare corners as it’s faster

1 Like

This is the forum I used to create my own projectiles. Uses velocity instead of the thing fastcast uses.

1 Like

image
Huh how can I forget? This could be used to make it more smoother too! Anyway thanks man!

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