Alright I have checked everything but it still seems that it is not working. I believe it is an issue with my rigging but I am not sure. Here is everything
Gun:
https://www.roblox.com/library/7056278933/gun
Viewmodel:
https://www.roblox.com/library/7056291724/viewmodel
FPS ModuleScript:
-- This is game.replicatedstorage.fps
-- Coolio module stuff
local handler = {}
local fpsMT = {__index = handler}
local replicatedStorage = game:GetService("ReplicatedStorage")
local spring = require(replicatedStorage.Modules.spring)
-- Functions i like using and you will probably too.
-- Bobbing!
local function getBobbing(addition,speed,modifier)
return math.sin(tick()*addition*speed)*modifier
end
-- Cool for lerping numbers (useful literally everywhere)
local function lerpNumber(a, b, t)
return a + (b - a) * t
end
function handler.new(weapons)
local self = {}
return setmetatable(self,fpsMT)
end
function handler:equip(wepName)
-- Explained how this works earlier. we can store variables too!
-- if the weapon is disabled, or equipped, remove it instead.
if self.disabled then return end
if self.equipped then self:remove() end
print("removed old gun")
-- get weapon from storage
local weapon = replicatedStorage.Weapons:FindFirstChild(wepName) -- do not cloen
if not weapon then return end -- if the weapon exists, clone it, else, stop
weapon = weapon:Clone()
print("weapon has been cloned")
--[[
Make a viewmodel (easily accessible with weapon.viewmodel too!)
and throw everything in the weapon straight inside of it. This makes animation hierarchy work.
--]]
self.viewmodel = replicatedStorage.viewmodel:Clone()
print("viewmodel has been cloned")
for i,v in pairs(weapon:GetChildren()) do
v.Parent = self.viewmodel
if v:IsA("BasePart") then
v.CanCollide = false
v.CastShadow = false
end
end
-- Time for automatic rigging and some basic properties
self.camera = workspace.CurrentCamera
self.character = game.Players.LocalPlayer.Character
-- Throw the viewmodel under the map. It will go back to the camera the next render frame once we get to moving it.
self.viewmodel.rootPart.CFrame = CFrame.new(0,-100,0)
print("set viewmodel rootpart cframe")
-- We're making the gun bound to the viewmodel's rootpart, and making the arms move along with the viewmodel using hierarchy.
self.viewmodel.rootPart.weapon.Part1 = self.viewmodel.WeaponRootPart
self.viewmodel.left.leftHand.Part0 = self.viewmodel.WeaponRootPart
self.viewmodel.right.rightHand.Part0 = self.viewmodel.WeaponRootPart
print("set all part motor6d stuff")
-- I legit forgot to do this in the first code revision.
self.viewmodel.Parent = workspace.Camera
print("viewmodels parent is the workspaces' camera")
--[[
Real life example:
self.loadedAnimations.idle = self.viewmodel.AnimationController:LoadAnimation(self.settings.anims.viewmodel.idle)
self.loadedAnimations.idle:Play()
self.tweenLerp("equip","In")
self.playSound("draw")
--]]
self.equipped = true -- Yay! our gun is ready.
end
function handler:remove()
-- Not much to see here yet. even the real life function for removing a weapon takes like 30 lines ***on the client***.
self.viewmodel:Destroy()
self.viewmodel = nil
self.equipped = false -- Nay! your gun is gone.
end
function handler:aim(toaim)
-- we'll be using this soon
end
function handler:update(deltaTime)
-- IF we have a gun right now. We're checking the viewmodel instead for "reasons".
if self.viewmodel then
print("There is a viewmodel")
self.viewmodel.rootPart.CFrame = self.camera.CFrame
print("The viewmodel's rootpart's cframe is the camera's cframe")
end
end
--[[
Used in my real game for framerate counting. I kept it in for fun.
(decomissioned since like 3 months ago, don't use this)
spawn(function()
local fps = 0
game:GetService("RunService").RenderStepped:Connect(function()
fps = fps + 1
end)
while wait(1) do
local gui = game.Players.LocalPlayer.PlayerGui:FindFirstChild("wepGui")
if gui then
gui.FPScount.Text = string.format("FPS: %s",fps)
end
fps = 0
end
end)
--]]
return handler
InputController:
-- input controller
-- The fps module we're about to add
local weaponHandler = require(game.ReplicatedStorage.Modules.fps)
print("got the wep handler")
--Custom input service. Do this how you want, i just couldn't ever remember how to use other services consistently.
local velocity = require(game.ReplicatedStorage.Modules.Velocity):Init(true)
print("got velocity and have inited")
local inputs = velocity:GetService("InputService")
print("got inputservice")
--Current weapon and translating binds from integer to enum. You don't need to understand that.
local curWeapon = nil
print("set var curWeapon")
local enumBinds = {
[1] = "One";
[2] = "Two";
[3] = "Three";
}
print("set var enumBinds")
-- Server security. We don't need this right now, so i'll just comment it.
-- local weps,primaryAmmo,secondaryAmmo = game.ReplicatedStorage.weaponRemotes.New:InvokeServer()
--[[
This means if you add a second weapon it'll automatically go under the bind 2,3, etc.
This is a bad thing, at least for later stages. The above commented line shows that we
should get the weapons from the server on-spawned. Here's how it looks in my game:
local defaultWeapons = {
[1] = "UMP45";
-- [2] = "JESUS"; lol railgun
}
--]]
local weps = game.ReplicatedStorage.Weapons:GetChildren()
print("got weps")
local weapon = weaponHandler.new(weps)
print("got the weapon")
print(weapon)
-- clearing viewmodels we could have kept in the camera because of script errors and stuff
local viewmodels = workspace.Camera:GetChildren()
print("got viewmodels from workspace camera")
print(viewmodels)
for i,v in pairs(viewmodels) do
if v.Name == "viewmodel" then
v:Destroy()
print("destroyed old viewmodel")
end
end
-- equip code
for i,v in pairs(weps) do
-- cooldown for spammy bois
local working
-- we will bind this per-weapon
local function equip()
-- if cooldown active, then don't execute the function. for less experienced scripters, this is just the equivalent of:
--[[
local function brug()
if working == false then
-- do stuff
end
end
--]]
if working then return end
working = true
-- if the current equipped weapon is different from the one we want right now (also applies to the weapon being nil)
if curWeapon ~= v then
if weapon.equipped then
weapon:remove()
end
weapon:equip(v.Name)
print("equipped weapon")
curWeapon = v
print("curWeapon is: "..tostring(curWeapon))
else
-- if it's the same, just remove it
spawn(function()
weapon:remove()
end)
curWeapon = nil
end
working = false
end
-- This means you can have 3 different weapons at once.
inputs.BindOnBegan(nil,enumBinds[i],equip,"Equip : "..i)
print("on input began")
end
local function update(dt)
weapon:update(dt)
end
-- marking the gun as unequippable
game.Players.LocalPlayer.Character:WaitForChild("Humanoid").Died:Connect(function() weapon:remove() weapon.disabled = true end)
game:GetService("RunService").RenderStepped:Connect(update)
print("updated")
Still, no errors.
If you need anything else let me know.
EDIT: All my folders and scripts are PascalCase, so ignore that.