local FRAMEWORK = {}

local PLAYERS = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local UserInputService = game:GetService("UserInputService")

local fldr_MODULES = ReplicatedStorage:FindFirstChild("Modules")
local fldr_WEAPONS = ReplicatedStorage:FindFirstChild("Weapons")
local fldr_SKINS = ReplicatedStorage:FindFirstChild("Skins")
local fldr_VIEWMODELS = ReplicatedStorage:FindFirstChild("Viewmodels")

local mod_SPRING = require(fldr_MODULES:FindFirstChild("Spring"))
local spr_RECOIL = mod_SPRING.new()

local PLAYER = PLAYERS.LocalPlayer
local w_CHARACTER = PLAYER.Character or PLAYER.CharacterAdded:Wait()

local w_CAMERA = workspace.CurrentCamera -- Player's current camera
local vm_SWAY = 0.25 -- Viewmodel sway amount
local vm_SwayCF = CFrame.new() -- Viewmodel sway CFrame
local cam_LastCFrame = CFrame.new() -- Last camera CFrame

FRAMEWORK.inv_TOTAL = {} -- Total invetory, all weapons
FRAMEWORK.inv_CURRENT = {} -- Current inventory, currently equipped weapons
FRAMEWORK.inv_CURRENT.MAX = 3 -- Max of three weapons to carry around; primary, secondary, melee
FRAMEWORK.inv_DEFAULT = { -- DEFAULT INVENTORY
    "Railgun", -- Primary, [1]
    "Handcannon", -- Secondary, [2]
    "Gaster Blaster", -- Melee, [3]
};

FRAMEWORK.cur_SKIN = "The Stranded" -- Player's current equipped skin
FRAMEWORK.cur_VIEWMODEL = "v_" .. FRAMEWORK.cur_WEAPON -- Player's current viewmodel
FRAMEWORK.cur_WEAPON = inv_DEFAULT[2] -- Current equipped weapons

function FRAMEWORK:WeldWeapon(WEAPON) -- Quick way to weld weapons to a blank viewmodel if no viewmodel exits
    local weap_MAIN = WEAPON:FindFirstChild("Handle")
    
    for i, v in ipairs(WEAPON:GetDescendants()) do
        if v:IsA("BasePart") v ~= weap_MAIN then
            local MOTOR = Instance.new("Motor6D", weap_MAIN)
            MOTOR.Name = "motor_" .. string.upper(v.Name)
            MOTOR.Part0 = weap_MAIN
            MOTOR.Part1 = v
            MOTOR.C0 = MOTOR.C0.CFrame:Inverse() * MOTOR.Part1.CFrame
        end
    end
end

function FRAMEWORK:GetCurrentSkin() -- Return the player's skin (MODEL)
    for i, v in pairs(fldr_SKINS:GetChildren()) do
        if v:IsA("Model") and v.Name == FRAMEWORK.cur_SKIN then
            return v
        end
    end
end

function FRAMEWORK:GetSkinViewmodel() -- Returns the player's skin viewmodel
    for i, v in pairs(fldr_VIEWMODELS:FindFirstChild("Arms"):GetChildren()) do
        if v:IsA("Model") and v.Name == FRAMEWORK.cur_SKIN then
            return v
        end
    end
end

function FRAMEWORK:GetViewmodelFromCamera() -- Returns the player's viewmodel from the camera
    for i, v in pairs(w_CAMERA:GetChildren()) do
        if v:IsA("Model") and string.find(v.Name, "v_") then
            return v
        end
    end
end

function FRAMEWORK:GetLastUsedWeapon(weap_NEW) -- guh
    local weap_LAST = cur_WEAPON
end

local function GetBobbing(ADD)
    return math.sin(tick() * ADD * 1.3) * 0.5
end

function FRAMEWORK:Equip(VIEWMODEL)
    
end

function FRAMEWORK:Remove(VIEWMODEL)
    
end

function FRAMEWORK:Reload(VIEWMODEL, anim_RELOAD)
    local RELOAD = VIEWMODEL.AnimationController:LoadAnimation(anim_RELOAD)
    RELOAD.Looped = false
    RELOAD:Play()
    RELOAD.Stopped:Wait()

    return 30
end

function FRAMEWORK:Update(VIEWMODEL, DELTATIME, spr_RECOIL, spr_BOB, spr_SWAY) -- Updates the player's viewmodel (USE RUN SERVICE NERD)
    VIEWMODEL.HumanoidRootPart.CFrame = w_CAMERA.CFrame -- Set's the VM HRP CFrame to the player's camera

    local BOBBLE = Vector3.new(GetBobbing(10), GetBobbing(5), GetBobbing(5))
    spr_BOB:Shove(BOBBLE / 10 * (w_CHARACTER.HumanoidRootPart.Velocity.Magnitude) / 10) -- Shoves the bob to be based off character movement
    
    local MouseDelta = UserInputService:GetMouseDelta()
    spr_SWAY:Shove(Vector3.new(-MouseDelta.X / 500, MouseDelta.Y / 200, 0)) -- Shoves the sway to be based on player's mouse movements
    
    local spr_RecoilUPDATE = spr_RECOIL:Update(DELTATIME) -- Updates the Recoil spring
    local spr_BobUPDATE = spr_BOB:Update(DELTATIME) -- Updates the Bobbing spring
    local spr_SwayUPDATE = spr_SWAY:Update(DELTATIME) -- Updates the Swaying spring

    VIEWMODEL.HumanoidRootPart.CFrame = VIEWMODEL.HumanoidRootPart.CFrame:ToWorldSpace(CFrame.new(spr_BobUPDATE.Y, spr_BobUPDATE.X, 0))
    VIEWMODEL.HumanoidRootPart.CFrame *= CFrame.new(spr_SwayUPDATE.X, spr_SwayUPDATE.Y, 0)
    
    VIEWMODEL.HumanoidRootPart.CFrame *= CFrame.Angles(math.rad(spr_RecoilUPDATE.X) * 2, 0)
    w_CAMERA.CFrame *= CFrame.Angles(math.rad(spr_RecoilUPDATE.X), math.rad(spr_RecoilUPDATE.Y), math.rad(spr_RecoilUPDATE.Z))
end

return FRAMEWORK

Embed on website

To embed this project on your website, copy the following code and paste it into your website's HTML: