Quick overview, but please view the code sample and the screenshots:
It’s quite weird, but sometimes the gun shoots from below the map. I’m not sure if it’s the code or the attachment.
-
What do you want to achieve?
I need help fixing my FPS system that is based off of Writing an FPS framework (2020) (Check it out if you haven’t, it is a great tutorial!), parts 1 and 2. Everything is working great except for the actual firing. -
What is the issue? Include screenshots / videos if possible!
The gun sometimes fires from below the map. I have no clue why exactly, I have not yet detected a pattern. Things to note: The receiver itself is facing backwards, but the attachment is facing forward. To test, I added small blocks to trace the bullet and large blocks for the point where it fires from (Large purple is the position, and large black is the position and orientation).
Screenshots:
Receiver information and position (Note that the way the mesh is imported it is backward, I will fix it soon, but it shouldn’t be a problem):
Attachment information (Should be facing backward in relation to the its parent the receiver):
Finally, the main photo of the shots under the map:
The orientation seems to be fine for some reason.
The code for firing (The handler works fine, but I can add the code if you want. Let me know.)
You don’t have to read it all right away if you don’t want, the important lines are below. Its included in case anyone notices problems with it:
function handler:fire(tofire)
--Requirements for firing here, there are a lot so I cut them out.
-- this makes the loop stop running when set to false
self.firing = tofire
if not tofire then return end
-- while lmb held down do
local function fire(semi)
if self.ammo[self.wepName] <= 0 then return end
-- It's better to replicate the change to other clients and play it there with the same code as here instead of using SoundService.RespectFilteringEnabled = false
local sound = self.viewmodel.receiver.pewpew:Clone()
sound.Parent = self.viewmodel.receiver
sound:Play()
game:GetService("Debris"):AddItem(sound,5)
self.loadedAnimations.fire:Play()
self.ammo[self.wepName] = self.ammo[self.wepName] - 1
--local origin = self.viewmodel.receiver.barrel.WorldPosition
--local direction = self.viewmodel.receiver.barrel.WorldCFrame
-- addition of deltatime here is a poor attempt at fixing the recoil being framerate based
-- this doesn't happen in my own game, dunno why
local min = self.settings.firing.recoil.min
local max = self.settings.firing.recoil.max
local random = Random.new(tick())
local amount = Vector3.new(random:NextNumber(min.x, max.x),random:NextNumber(min.y, max.y), random:NextNumber(min.z, max.z))
if not semi then
self.springs.fire:shove(amount * self.deltaTime * 60)
spawn(function()
wait(self.settings.firing.recoil.tim)
self.springs.fire:shove(amount * Vector3.new(-1,-1,-1) * self.deltaTime * 60)
end)
end
-- Muzzle flash. This is why we left it invisible and enabled.
coroutine.wrap(function()
-- could be optimized a lot
-- flash flashes inside the barrel, and smoke smokes for a short time
for i,v in pairs(self.viewmodel.receiver.barrel:GetChildren()) do
if v.Name == "flash" then
v.Transparency = NumberSequence.new(v.transparency.Value)
elseif v.Name == "smoke" then
v.Enabled = true
end
end
wait()
for i,v in pairs(self.viewmodel.receiver.barrel:GetChildren()) do
if v.Name == "flash" then
v.Transparency = NumberSequence.new(1)
elseif v.Name == "smoke" then
v.Enabled = false
end
end
end)()
-- origin, direction
-- barrel because realism, camera.CFrame because uh accuracy and arcadeying
-- make sure the barrel is facing where the gun fires
-- aaand make sure the gun is actually facing towards the cursor properly, players don't like offsets
local origin = self.viewmodel.receiver.barrel.WorldPosition
local part = Instance.new("Part")
part.Size = Vector3.new(4,4,4)
part.Anchored = true
part.Position = origin
part.Name = "ORIGIN"
part.Parent = workspace.fastCast
part.BrickColor = BrickColor.new("Black")
local direction = self.viewmodel.receiver.barrel.WorldCFrame
local part = Instance.new("Part")
part.Size = Vector3.new(4,4,4)
part.Anchored = true
part.CFrame = direction
part.Name = "Direction"
part.Parent = workspace.fastCast
part.BrickColor = BrickColor.new("Royal purple")
-- inconsistent :(
fastcastHandler:fire(origin, direction, self.settings)
print("FIRE CHECK 2")
if type(self.settings.firing.automatic) ~= "number" then
wait(60/self.settings.firing.rpm)
end
end
if self.settings.firing.automatic and type(self.settings.firing.automatic) ~= "number" then
repeat
self.canFire = false
fire()
self.canFire = true
until self.ammo[self.wepName] <= 0 or not self.firing
elseif type(self.settings.firing.automatic) == "number" then
local amount = 1
repeat
self.canFire = false
if amount == self.settings.firing.automatic then
fire()
else
fire(true)
end
self.canFire = true
amount += 1
wait(0.1)
until self.ammo[self.wepName] <= 0 or amount > self.settings.firing.automatic
self.canFire = false
wait(60/self.settings.firing.rpm)
self.canFire = true
else
self.canFire = false
fire()
print("FIRECHECK1")
self.canFire = true
end
if self.ammo[self.wepName] <= 0 then
self.firing = false
end
end
Specific lines:
local origin = self.viewmodel.receiver.barrel.WorldPosition
local direction = self.viewmodel.receiver.barrel.WorldCFrame
fastcastHandler:fire(origin, direction, self.settings)
-
What solutions have you tried so far?
I flipped the attachment around, as I noticed it was facing the wrong way. I’ve mainly messed around with the attachment, but I have not noticed an issue with the code.
If any part of the system does not make sense, feel free to ask me a question or refer to the tutorial linked above.
Thanks for reading!