Designing an FPS Framework: Beginner’s guide [PART 2]

thanks for explaining it i did not understand it the way you said it

Thanks to you I was able to make my first fps! https://gyazo.com/6eecd951403e1ef9141bf9247d691a3d

2 Likes

Can you make SpringModule into a free model? I can’t open .rbxm files

Gotchu

2 Likes

:joy_cat:

Exactly one minute ago I resolved and found out how to open .rblx files

At least you helped someone else I guess

:joy_cat:

1 Like

That cannon model looks amazing! Where did you find it?

1 Like

I just found it in the toolbox. Search up tf2 weapons

1 Like

nice job buddy, nice video. Here’s some hearts <3

1 Like

but why are videos outdated doe.

Hello, I cant get the sway working. Could you help me fix it?
MainModule:

local module = {}
local function getbobbing(addition)
	return math.sin(tick() * addition * 1.3) * 0.5
end
function module.update(viewmodel,dt,recoilspring,bobblespring,swayingspring)
	viewmodel.HumanoidRootPart.CFrame = workspace.Camera.CFrame
	local bobble = Vector3.new(getbobbing(10),getbobbing(5),getbobbing(5))
	local mousedelta = game:GetService("UserInputService"):GetMouseDelta()
	local character = game.Players.LocalPlayer.Character or game.Players.LocalPlayer.CharacterAdded:Wait()
	bobblespring:shove(bobble / 10 * (character:WaitForChild("HumanoidRootPart").Velocity.Magnitude) / 10)
	local updatedrecoilspring = recoilspring:update(dt)
	local updatedbobblespring = bobblespring:update(dt)
	local updatedswayspring = swayingspring:update(dt)
	print(mousedelta)
	viewmodel.HumanoidRootPart.CFrame = viewmodel.HumanoidRootPart.CFrame:ToWorldSpace(CFrame.new(updatedbobblespring.Y,updatedbobblespring.X,0))
	viewmodel.HumanoidRootPart.CFrame *= CFrame.new(updatedswayspring.X,updatedswayspring.Y,0)
	viewmodel.HumanoidRootPart.CFrame *= CFrame.Angles(math.rad(updatedrecoilspring.X) * 2,0,0)
	workspace.Camera.CFrame *= CFrame.Angles(math.rad(updatedrecoilspring.X),0,0)
end
function module.weldgun(gun)
	local Main = gun.GunComponents.Handle
	for i,v in ipairs(gun:GetDescendants()) do
		if v:IsA("BasePart") and v ~= Main then
			local new_motor6D = Instance.new("Motor6D")
			new_motor6D.Name = v.Name
			new_motor6D.Part0 = Main
			new_motor6D.Part1 = v
			new_motor6D.C0 = new_motor6D.Part0.CFrame:inverse() * new_motor6D.Part1.CFrame
			new_motor6D.Parent = Main
		end
	end
end
function module.equip(viewmodel,gun,hold)
	local gun_handle = gun.GunComponents.Handle
	local HRP_Motor6D = viewmodel:WaitForChild("HumanoidRootPart").Handle
	gun.Parent = viewmodel
	HRP_Motor6D.Part1 = gun_handle
	local Hold = viewmodel.AnimationController:LoadAnimation(hold)
	Hold:Play()
end
function module.cast(gun,endposition,velocity)
	local gunbarrel = gun.GunComponents.Muzzle
	local bullet = Instance.new("Part")
	bullet.Size = Vector3.new(0.5,0.5,2.5)
	bullet.Anchored = true
	bullet.CanCollide = false
	bullet.Color = Color3.new(219,239,0)
	bullet.Material = Enum.Material.Neon
	bullet.Parent = workspace
	bullet.CFrame = CFrame.new(gunbarrel.Position,endposition)
	local Loop
	Loop = game:GetService("RunService").RenderStepped:Connect(function(dt)
		bullet.CFrame *= CFrame.new(0,0,-velocity * (dt * 60))
		if (bullet.Position - gunbarrel.Position).magnitude > 5000 then
			bullet:Destroy()
			Loop:Disconnect()
		end
	end)
end
return module

If you need the localscript just tell me.
Thanks for the help!

1 Like

Mind sending me the local script? thanks.

Absolutely:

local gameworkspace = game:GetService("Workspace")
local gamereplicatedstorage = game:GetService("ReplicatedStorage")
local servicerunservice = game:GetService("RunService")
local serviceuserinputservice = game:GetService("UserInputService")
local gunmodel = gamereplicatedstorage:WaitForChild("Cannon")
local viewmodel = gamereplicatedstorage:WaitForChild("Viewmodel")
local camera = workspace.Camera
local animationsfolder = gamereplicatedstorage:WaitForChild("Cannon_Animations")
local mainmodule = require(gamereplicatedstorage:WaitForChild("MainModule"))
local springmodule = require(gamereplicatedstorage:WaitForChild("SpringModule"))
local recoilspring = springmodule.new()
viewmodel.Parent = gameworkspace.Camera
mainmodule.weldgun(gunmodel)
local bobblespring = springmodule.new()
local swayingspring = springmodule.new()
servicerunservice.RenderStepped:Connect(function(dt)
	mainmodule.update(viewmodel,dt,recoilspring,bobblespring,swayingspring)
end)
local IsPlayerHoldingMouse
local canfire = true
local firedelay = 2.9
servicerunservice.Heartbeat:Connect(function(dt)
	if IsPlayerHoldingMouse then
		if canfire then
			gunmodel.GunComponents.Muzzle.Fire.Enabled = true
			gunmodel.GunComponents.Muzzle.fire:Play()
			canfire = false
			mainmodule.cast(gunmodel,game.Players.LocalPlayer:GetMouse().Hit.Position,2)
			recoilspring:shove(Vector3.new(7,0,0))
			wait(0.1)
			gunmodel.GunComponents.Muzzle.Fire.Enabled = false
			wait(firedelay)
			canfire = true
		end
	end
end)
mainmodule.equip(viewmodel,gunmodel,animationsfolder.Hold)
serviceuserinputservice.InputBegan:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		IsPlayerHoldingMouse = true
	end
end)
serviceuserinputservice.InputEnded:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		IsPlayerHoldingMouse = false
	end
end)

Ah actually I just noticed. You forgot to shove the sway spring.

image

1 Like

Hey, I loved your tutorial. I gotta ask, whats your studio font?

I use JetBrains Mono for vscode and Jetbrains Mono Semibold for Roblox Studio.

1 Like

It would be nice for one day there would be a reload tutorial.

yeah there needs to be an ammo system that would be cool

my gun turns sideways when zooming in

module:

function module.update(viewmodel, dt, recoil, bobbleing, swaying, gun)
	viewmodel.HumanoidRootPart.CFrame = game.Workspace.Camera.CFrame
	
	local bobble = Vector3.new(getbobbing(10),getbobbing(5),getbobbing(5))
	local delta = game:GetService("UserInputService"):GetMouseDelta()
	local char = game.Players.LocalPlayer.Character or game.Players.LocalPlayer.CharacterAdded:Wait()
	bobbleing:shove(bobble / 15 * (char.HumanoidRootPart.Velocity.Magnitude) / 15)
	swaying:shove(Vector3.new(-delta.X / 500), delta.Y / 200, 0)

	local updatedrecoil = recoil:update(dt)
	local updatedbobble = bobbleing:update(dt)
	local updatedsway = swaying:update(dt)
	
	gun.GunComponents.Sight.CFrame = gun.GunComponents.Sight.CFrame:Lerp(viewmodel.HumanoidRootPart.CFrame, game.ReplicatedStorage.Values.AimAlpha.Value)
	
	viewmodel.HumanoidRootPart.CFrame = viewmodel.HumanoidRootPart.CFrame:ToWorldSpace(CFrame.new(updatedbobble.Y, updatedbobble.X, 0))
	viewmodel.HumanoidRootPart.CFrame *= CFrame.new(updatedsway.X, updatedsway.Y, 0)
	viewmodel.HumanoidRootPart.CFrame *= CFrame.Angles(math.rad(updatedrecoil.X) * 2,0,0)
	game.Workspace.Camera.CFrame *= CFrame.Angles(math.rad(updatedrecoil.X),math.rad(updatedrecoil.Y),math.rad(updatedrecoil.Z))
end

function module.aim(toaim, viewmodel, gun)
	if toaim then
		game:GetService("TweenService"):Create(game.ReplicatedStorage.Values.AimAlpha, TweenInfo.new(1), { Value = 1}):Play()
	else
		game:GetService("TweenService"):Create(game.ReplicatedStorage.Values.AimAlpha, TweenInfo.new(1), { Value = 0}):Play()
	end
end

local:

game:GetService("UserInputService").InputBegan:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		md = true
	elseif input.UserInputType == Enum.UserInputType.MouseButton2 then
		module.aim(true, viewmodel, grozamodel)
	end
end)

game:GetService("UserInputService").InputEnded:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		md = false
	elseif input.UserInputType == Enum.UserInputType.MouseButton2 then
		module.aim(false, viewmodel, grozamodel)
	end
end)

Ah this is a simple fix, you simply just need to rotate the AimPart so the rotation is correct, you can check the orientation by inserting a decal inside the Part.

1 Like

yeah figured that out but in your video it slowly moves into the aim but in my game it just snaps to it