I moved the server script into ServerScriptService, adjusted it a bit, so all “guns” works off that single script. Not sure if it’s a good idea but at least the bullets don’t stay in the air anymore.
This is the ideal way to do it. A master script that serves as a unified spawner for all bullets of the same type.
Would it be possible to visualize the projectile’s trajectory with beams when using this module? Say, something like this. A use case example would be if you want aiming to be easier for users in your game.
I’m having issues with armour pieces blocking the bullets from damaging a target. Is there a way to whitelist them so that bullets can go through them?
Also, is there a way to maybe have each bullet act as a straight beam rather than individual bolts?
If I had to guess I’d say that the “GunFirePoint” isn’t exactly where it should be, since bullets should start at the position of the that fire point attachment.
@Xan_TheDragon
Is there any plan to implement the bullet penetration system based on the part’s thickness?
Since I’ve tried using this method, for example, BasePart.Size.X/Y/Z but it doesn’t work accurately since if the projectile is coming from the x-axis but the code check for the z-axis part size and I don’t know how to check what axis of where the projectile is coming from.
I’ve tried using this method but I can’t get it to work using your FastCast system.
I’ve implemented bullet trails in my game. The issue is that they don’t replicate very well from the server to the client. Do you think it would be a good idea for the server to simulate the cast as well as send the cast data to the client so the client can create the cast locally and simulate the trail.
I’m sorry, i replied the wrong person, but when i do this, it give me an error ‘‘Cannot statically invoke method ‘ReturnPart’ - It is an instance method. Call it on an instance of this class created via PartCache.new’’
I am using this in my game to power dodgeballs. It is creating a lot of network issues. Players lagging and jumping around etc…
I used the example raygun provided, changed it to be a ball shape, and to only shoot one ball every 1.5 seconds. Any ideas on why its causing such significant network jitter when there are only ever 4-5 balls bouncing around at any given time?
Is there any way to prevent shooting through walls?
Hey, I’ve been using your module and its fantastic. However I have little criticism on the documentation. I was curious is Caster:Fire() returned the activeCast however your docs don’t go over if it does. I had to read the module’s code instead. It would be fantastic if you made this small adjustment to the documentation so people don’t have to go through the confusion I had to. Aside from that your documentation is fantastic I really appreciate the effort put into this module
Sorry I am late. Of the replies I have read that pose new questions, here’s some answers:
The method given on that thread seems like it would work. You basically just need to do a raycast in your pierce callback. The origin of the ray should be exactly how the thread describes it: some distance in the same direction of the incoming ray, and then the direction of the new ray is the opposite of the bullet’s direction.
This will have issues if you have a very large part and bullet drop, because this method can’t figure out where a curve will start and end within a part, doing that will be quite complicated…
The error message says exactly what you need to do:
local cache = PartCache.new()
local part = cache:GetPart()
not
local part = PartCache:GetPart()
A static invocation means that you called the method on the actual module itself rather than one of the module’s custom objects that is, again, created via PartCache.new().
That’s in the method signature.
The format all methods follow is ReturnType Name(parameters...)
- if a function returns nothing, its return type is void
in lieu of typical programming terms. In this case, it means the method’s name is Fire, and it returns an ActiveCast instance.
hello, I was reviewing the module and found a programming error. Basically maximum distance doesn’t work on rays that don’t have physics, since they only produce raycast per update.
Don’t you understand me?, I’ll explain: the distance is checked when the trajectory is updated, which means that you will have to wait for the trajectory to update to check the distance.
This would not be affected on ranged weapons, but on handheld weapons; you have to wait for the raycast to update and the distance would never be correct.
I suggest checking the distance in one heartbeat from the last point - the origin.
This module is amazing but I have one issue.
How can I get the player thats firing the caster?
Unlike the example code I dont use a script / remote event inside of the tool.
I have one remote event that every player uses that connects to a script inside of serverscriptservice so multiple people use the same caster.
How do I get the player that fired the caster? For my OnHit event I need to get the player dealing damage before dealing damage to another player so I can do some checks.
You can get the active cast object and stuff it in the UserData folder like so, from the active cast documentation.
local activeCast = currentEntityFastCastHandler:Fire(origin, direction)
local bulletOwner = world.Get(entity, PlayerComponent)
activeCast.UserData.Owner = bulletOwner
activeCast.UserData.BulletID = bulletID --bulletID system
ProjectileService.ReplicateProjectileClientToServer:Fire(origin, direction, attachment, bulletID)
to identify the owner
local function rayHit(activeCast, result: RaycastResult, segmentVelocity, bullet)
local instanceHit: BasePart = result.Instance
local owner = activeCast.UserData.Owner
--do stuff
end
local castComponent = entityFastCastHandler.fastcast
local replicationRayHitSignal = castComponent.RayHit:Connect(rayHit)
Thank you for the help! Greatly appreciated.
Is there a way to get the cosmetic part? I want to do something with the cosmetic bullet.
In what situations could RayHit
not fire, but LengthChanged
and CastTerminated
do? I am having a problem with this. It could be an issue on my end but I can’t find any cases in the docs where this could happen. I don’t manually terminate the cast.
guns[player] = {
caster = caster,
behavior = behavior,
connections = {
caster.RayHit:Connect(function(_, result: RaycastResult)
print("RayHit")
end),
caster.LengthChanged:Connect(function(
_, origin: Vector3, direction: Vector3, length: number, _, bullet: BasePart
)
print("LengthChanged")
end),
caster.CastTerminating:Connect(function(cast)
print("CastTerminating")
end)
}
}
I can send a place file, but that is what I have.
RayHit will not fire if the ray is terminated due to exceeding its maximum distance, hence why the docs say to handle bullet disposal in CastTerminating, not RayHit. RayHit is not guaranteed to fire (if it terminates due to exceeding maximum distance, it didn’t hit anything, so it would break the contract of the hit never being nil in RayHit if it did fire that event). CastTerminating, on the other hand, is guaranteed to always fire for any given cast.
Great Modulescript. One Problem tho: It completely breaks Projectiles that use Trails (The first 2 ones are with the Module, the last one is without the modulescript)