It’s your sample script I didn’t change anything related to the gun script, I just added a team filter.
Yes, I took it from Toolbox today.
It’s your sample script I didn’t change anything related to the gun script, I just added a team filter.
Yes, I took it from Toolbox today.
I’ve found the problem. The example gun should fire at your cursor. I did Mouse.Hit.lookVector
which is the direction from your camera to Mouse.Hit.p
. Now it goes from the handle’s WorldFirePoint attachment like it should.
My mistake - I hadn’t realized this would happen. The example should function properly now.
Yes this is now working very well, Thank You!
I will give more feedback on how it performs when I get more people to test it.
I just ask a little question
Is there a good way to ignore characters’ accesories when cast ray? I mean I tried my own way but did not work
edit: nvm i figured out
Heya folks!
I’ve just pushed version 7.0.0 to address some recent requests. It is now possible to apply acceleration (not just velocity!) to individual bullets! This is great for things like sniper rifles where the wind affects the curvature of individual bullets as they fly, more specifically where the wind may change in realtime.
Have a look at the new API for more details. https://github.com/XanTheDragon/FastCastAPIDocs/wiki/API#version-700
Hey i’m trying to use this for my projectiles in the game, but i’m running into a problem where the arrow isn’t moving, I also get no errors, here’s the script section
.
local Attack = game.Lighting.Parts.SpiritArrow:Clone()
Attack.Name = "Attack"
Attack.Anchored = true
Attack.CanCollide = false
Attack.TopSurface = 0
Attack.BottomSurface = 0
Attack.BrickColor = Player.AbilityColor.Value
Attack.Reflectance = 0
Attack.CFrame = CFrame.new(char.RightHand.Position+Vector3.new(0,5,0), Vector3.new(MouseEvents.MousePos.Value.X,MouseEvents.MousePos.Value.Y,MouseEvents.MousePos.Value.Z))
Attack.Parent = workspace
local Distance = (Vector3.new(MouseEvents.MousePos.Value.X,MouseEvents.MousePos.Value.Y,MouseEvents.MousePos.Value.Z)*1000)
local Speed = (Vector3.new(MouseEvents.MousePos.Value.X,MouseEvents.MousePos.Value.Y,MouseEvents.MousePos.Value.Z) * 60)
Caster:Fire(char.RightHand.Position+Vector3.new(0,5,0), Distance, Speed, Attack)
Here’s what’s happening in a gif (I put arrow spawning in the air on purpose, and again I get no errors in output)
Did you remember to CFrame the arrow on the LengthChanged event?
Caster.LengthChanged:Connect(function (CastOrigin, SegmentOrigin, SegmentDirection, Length, CosmeticBulletObject)
CosmeticBulletObject.CFrame = CFrame.new(SegmentOrigin, SegmentOrigin + SegmentDirection)
end)
I suggest checking out the example code (https://www.roblox.com/library/2009153526/FastCast-Example-Laser-Gun) for more usage.
Sorry for bumping an old thread but, how come the bullet Hit detection for me doesn’t really work?
here’s the GIF here:
and here’s the script portion:
function OnRayHit(HitPart, HitPoint, Normal, Material, CosmeticBulletObject)
--This function will be connected to the Caster's "RayHit" event.
CosmeticBulletObject:Destroy() --Destroy the cosmetic bullet.
if HitPart and HitPart.Parent then --Test if we hit something
local Humanoid = HitPart.Parent:FindFirstChildOfClass("Humanoid") --Is there a humanoid?
if Humanoid then
Humanoid:TakeDamage(10) --Damage.
end
MakeParticleFX(HitPoint, Normal) --Particle FX
end
end
function OnRayUpdated(CastOrigin, SegmentOrigin, SegmentDirection, Length, CosmeticBulletObject)
--Whenever the caster steps forward by one unit, this function is called.
--The bullet argument is the same object passed into the fire function.
local BulletLength = CosmeticBulletObject.Size.Z / 2 --This is used to move the bullet to the right spot based on a CFrame offset
CosmeticBulletObject.CFrame = CFrame.new(SegmentOrigin, SegmentOrigin + SegmentDirection) * CFrame.new(0, 0, -(Length - BulletLength))
end
the hit detection is literally the same as the test weapon you have, but here’s the fire function, if there’s a problem with that.
local function shoot(Player, Direction)
--//Initialize
--if not canShoot(player, true) then return end
--shootSound:Play()
if tool.Parent:IsA("Backpack") then return end --Can't fire if it's not equipped.
--Note: Above isn't in the event as it will prevent the CanFire value from being set as needed.
if tool.Parent:IsA("Backpack") then return end --Can't fire if it's not equipped.
--Note: Above isn't in the event as it will prevent the CanFire value from being set as needed.
--We need to make sure the bullet inherits the velocity of the gun as it fires, just like in real life.
local HumanoidRootPart = tool.Parent:WaitForChild("HumanoidRootPart", 1) --Add a timeout to this.
local MyMovementSpeed = HumanoidRootPart.Velocity --To do: It may be better to get this value on the clientside since the server will see this value differently due to ping and such.
local ModifiedBulletSpeed = (Direction * BULLET_SPEED) + MyMovementSpeed --We multiply our direction unit by the bullet speed. This creates a Vector3 version of the bullet's velocity at the given speed. We then add MyMovementSpeed to add our body's motion to the velocity.
--Prepare a new cosmetic bullet
local Bullet = CosmeticBullet:Clone()
Bullet.CFrame = CFrame.new(FirePointObject.WorldPosition, FirePointObject.WorldPosition + Direction)
Bullet.Parent = workspace
Caster:Fire(FirePointObject.WorldPosition, Direction * BULLET_MAXDIST, ModifiedBulletSpeed, Bullet)
--We need to make sure the bullet inherits the velocity of the gun as it fires, just like in real life.
local HumanoidRootPart = tool.Parent:WaitForChild("HumanoidRootPart", 1) --Add a timeout to this.
local MyMovementSpeed = HumanoidRootPart.Velocity --To do: It may be better to get this value on the clientside since the server will see this value differently due to ping and such.
local ModifiedBulletSpeed = (Direction * BULLET_SPEED) + MyMovementSpeed --We multiply our direction unit by the bullet speed. This creates a Vector3 version of the bullet's velocity at the given speed. We then add MyMovementSpeed to add our body's motion to the velocity.
--Prepare a new cosmetic bullet
local Bullet = CosmeticBullet:Clone()
Bullet.CFrame = CFrame.new(FirePointObject.WorldPosition, FirePointObject.WorldPosition + Direction)
Bullet.Parent = workspace
Caster.LengthChanged:Connect(function (CastOrigin, SegmentOrigin, SegmentDirection, Length, CosmeticBulletObject)
CosmeticBulletObject.CFrame = CFrame.new(SegmentOrigin, SegmentOrigin + SegmentDirection)end)
Caster:Fire(FirePointObject.WorldPosition, Direction * BULLET_MAXDIST, ModifiedBulletSpeed, Bullet)
end
First of all, one major issue I see is that you fire the bullet twice in the fire function, and the connect the LengthChanged
event every single time after you fire both shots. It looks almost like you copied and pasted that entire chunk of code so it runs twice. This isn’t proper behavior. The template script I supplied had a correct layout, though for the sake of redundancy, this layout should include the following:
shoot
in your case. This function should only clone the cosmetic bullet (if necessary), calculate velocity (if necessary), and fire the caster with the needed parameters. It should not connect any caster events.LengthChanged
and RayHit
at the bottom of the script or wherever you see fit given your organizational preferences.To elaborate on #2 and #3 – You should connect to LengthChanged
and RayHit
outside of the shoot function. Think of it like any other event, like Tool.Activated
; you usually connect to this only once at the end of your script. This same ideology also applies to LengthChanged
and RayHit
– connect to them once and handle the data whenever they fire.
From what I can tell in the behavior of the bullets in the gif, you do not handle RayHit
correctly. If you indeed copied the code directly from my template, which you claim you did, the undesired behavior is likely caused by your shoot
function and its odd behavior. That, or you didn’t use Caster.RayHit:Connect(OnRayHit)
Try cleaning up the script a bit and ensuring that everything necessary is set up. If you’re still having issues, please send me a message and I’ll help you get it sorted out
Thank you so much for helping out! turns out the only thing needed was the Caster.RayHit:Connect(OnRayHit)
, and I’m sorry about my rookie mistakes, this was my first time using fastcast and I love how it works, I will definitely sort out through my code, but all I can say is that it definitely works. Thank you for responding in the thread!
edit once again, but it seems that my code is indeed, horrible! due to how the bullets were working, it multiplies the bullet every single time it is shot, and it deals more damage! I will look into why i made such a stupid mistake, and will edit my comment as to why this happened, lol.
edit edit: was because i put rayhit and lengthchanged inside the shoot function, sorry my bad.
You can probably replace the Signal library in this with this alternative. It’s faster than that Signal library.
local Signal = { }
Signal.__index = Signal
Signal.ClassName = "Signal"
local setmetatable = setmetatable
local running = coroutine.running
function Signal.new() return setmetatable({ }, Signal) end
function Signal:Fire(...)
for Index = 1, #self do
local Thread = coroutine.create(self[Index])
coroutine.resume(Thread, ...)
end
end
function Signal:Wait()
local Thread = running()
local function Yield(...)
self:Disconnect(Yield)
coroutine.resume(Thread, ...)
end
self[#self + 1] = Yield
return coroutine.yield()
end
function Signal:Connect(Function)
self[#self + 1] = Function
end
function Signal:Disconnect(Function)
local Length = #self
for Index = 1, Length do
if Function == self[Index] then
self[Index] = self[Length]
self[Length] = nil
break
end
end
end
function Signal:Destroy()
for Index = 1, #self do
self[Index] = nil
end
end
return Signal
It’s the fastest event library there is, using it can make FastCast more like FastestCast . It’s around 88% faster than the Signal you have currently.
Definitely some interesting work. I’ll be replacing the signal module, you’ll be credited of course.
In terms of your edits to the main module, I think I’ll only implement the changes that implement the new Signal module as soon, caching things like Vector3.new, math.sqrt, etc. will have no benefits in performance. Edit: It seems you’ve replied to this, so you’re aware of it already (Also see the second tweet, https://twitter.com/zeuxcg/status/1120508108445450241). Given that the performance increases from those changes at the moment are relatively negligible (very few use cases would require something faster than what’s already going on – I don’t think anyone needs to fire 500+ bullets per frame), I plan to continue using the older methods in anticipation of the new Lua VM, even if it’s some distance from release.
My friend @Validark made the original Signal module, but mine is faster and has an API that’s more like a BindableEvent. I think he deserves the credit more than me.
this module is working great so far, i needed something to stop the delay happenning for projectiles and this works perfectly. however for some reason it ignores the blacklist and still hits a part on it (local player character). the same goes for just shooting. sometimes the ray gets casted through an object thinking that there’s no object and therefor making the projectile go through the object.
I fixed the delay for projectiles by shooting on the client, and then only updating it for other players, so a for loop, checking if the player name is not the local player name (the one who fired the remote), then use FireClient
This is something I made, alternatively. I had a bullet system that tied to this and fired the impacted event, but you can just replace that with a bindable event if you’re willing to make the bullet system. :update() should be called on the created trajectory every RenderStepped, although it is still tied to time rather than an execution count.
Includes a reflection method for more complex weapons and wallbangs.
function physics.trajectory.new(initial, velocity)
local self = setmetatable({},{__index = physics.trajectory})
-- declaring critical variables
self.position = initial
self.velocity = velocity
self.impacted = event.new("impacted")
self.tracing = false
self.tracetype = "interface"
self.start = tick()
self.t = self.start
return self
end
function physics.trajectory:update()
local dt = tick() - self.t
self.t = tick()
self.position = self.position + (self.velocity * dt)
self.velocity = (self.velocity + .5 * Vector3.new(0,-1,0) * dt)
end
function physics.trajectory:reflect(normal)
self.trajectory = -2 * self.velocity.unit:Dot(normal.unit) * normal.unit + self.velocity.unit;
end
Wish the example gun included a spread/accuracy implementation.
Excellent point. That is a valuable piece of information for people looking to get into FPS/TPS design. I’ll get to adding that as soon as I can
Status update: This change is now live! Get the latest version of the example gun.
This is certainly interesting. I may not include such extensions natively (Only specific use cases may require something like bullet ricochet e.g. specific laser weapons. They aren’t prominent enough to add as part of the stock code) but I do most certainly encourage you to publish a module of your own to implement this stuff.
One immediate suggestion I have is adding a module that has FastCast as a child, where your module can automate casts and add extra functionality to bullets through pre-handled sequences.
Awesome, thanks for your work man!!!