Projectile Module (Help)

Hello, I’m LuaGirlDeveloper! I’m working on a projectile module and I need help with returning when the raycast hits something. If you look at FastCast, there’s a function that you can connect by using:

caster.RayHit:Connect(function()
  -- Code here
end)

Fastcast is a very “BALKANIZED” module, and it’s very hard to guess what version of it you are using.
Can you please attach or provide a link to the version that you are using?
Would also be nice to get an actual context instead of 2 lines of code.

Moreover, I recommend you use regular raycasting instead, since FastCast is pretty bloated and has features that you are never going to use yet are still loaded in memory.
Also, FastCast is a pretty outdated module by 2025 Luau standards.

You can use BindableEvents for this.

You can have your projectile class something like this…

Projectile = {
    HitEvent = Instance.new("BindableEvent")
    OnHit = HitEvent.Event
    --(other variables)
}

then in another script you can do

local myProjectile = Projectile.new(...) --(have a function that returns a new projectile (the table in the above code block))
myProjectile.OnHit:Connect(function(...)

end)

You can do the same with your projectile module by creating a BindableEvent (BindableEvent | Documentation - Roblox Creator Hub) or custom event and firing it when the raycast hits something…

local Projectile = {}
Projectile.RayHit = Instance.new("BindableEvent")

function Projectile:Fire(origin, direction)
    local ray = Ray.new(origin, direction)
    local hit, position = workspace:FindPartOnRay(ray)
    if hit then
        self.RayHit:Fire(hit, position)
    end
end

return Projectile

then you can connect to it like

local proj = require(ProjectileModule)

proj.RayHit.Event:Connect(function(hit, position)
    print("Hit part:", hit.Name)
end)

proj:Fire(Vector3.new(0,10,0), Vector3.new(0,-1,0))

This mimics FastCast (in this youtube video FastCast is beeing explained) behavior for hit detection!!

Hope this helps!!!

Why are you using method when you never get to use self?

Also wth bro its not 2018 why are you using FindPartOnRay?

Also BindableEvent is not intended for this use.

@Yarik_superpro, this module: FastCast: Redux - Creator Store

I forgot to mention I’m making a Projectile module that I can use for different Projectiles that have different attacks when the raycast hits so I need to detect when it hits and return where it hit and stuff.

I get what you are saying and thanks for pointing it out… but

I just wrote a quick example to show the idea of firing an event on hit, not really a production ready code. You are right that FindPartOnRay is outdated, i should have used workspace:Raycast (i think) instead since its faster and gives better control with RaycastParams.

(FindPartOnRay is older but it is still quick to write for simple straight line checks, which is why i used it in the example…)

local Projectile = {}
Projectile.RayHit = Instance.new("BindableEvent") -- just an example....

function Projectile:Fire(origin, direction, params)
    local result = workspace:Raycast(origin, direction, params)
    if result then
        self.RayHit:Fire(result.Instance, result.Position, result.Normal)
    end
end

return Projectile

Also about BindableEvent i KINDA what you mean… but for small modules it actually works fine as a quick way to expose events without having to build a full signal system!! It keeps the example easy to follow, especially for someone just getting started. In a larger scale system i would definitely switch to a custom signal or return the hit result directly, but for showing the idea it does the job.

The main point i was trying to get across was how to structure it so the module can expose an event like FastCast does!!!


My bad for dropping the older API in the quick example. :roll_eyes:

1 Like

The problem is signals itself;
You are not meant to make own signal systems in general.
There are some exeptions obviously if you want to make game “moddable” and with loadable content but that about it.

@Yarik_superpro would this work?

local Projectile = {}
Projectile.__index = Projectile

function Projectile.new()
	local self = setmetatable({}, Projectile)
	
	self.RaycastHit = Instance.new('BindableEvent')
	
	return self
end

function Projectile:Cast()
	-- Code here
	
	-- Hit code
	--self.RaycastHit:Fire() -- Send data and stuff
end

function Projectile:Clear()
	self.RaycastHit:Destroy()
end

return Projectile

Why?
You are not just overengineering but is also misusing and bloating the code for no gain but only perfomance loss.

Then how should I use it then? I don’t really know, Because I will have different projectiles and at this point, I may just create a module under it for the attack then call the attacks hit and run module then at this point.

@Yarik_superpro I found out my issue!

---- Script ----
local MyModule = require(script.Module)

local function MyFunction()
	print('Hello!')
end

MyModule.New(MyFunction)

---- Module ----
local Module = {}

function Module.New(Signal : Function)
	--> Hit detection and other checks
	Signal()
end

return Module

I never knew that you can pass a function into a module and call it when you want.

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