Designing an FPS Framework: Beginner's guide

Try and check if the HumanoidRootPart of the viewmodel is facing in the right direction, to do this just insert a decal and select it, then observe if the orange outline is facing in the right direction.

image

This is how it should look
If your still having trouble here is the viewmodel I used: viewmodel.rbxm (5.2 KB)

10 Likes

So far very good, im at this point in the code, and its giving the errorbelow and not putting the gun in the viewmodel, any idea whats happening?

 Handle is not a valid member of MeshPart "Workspace.Camera.Viewmodel.HumanoidRootPart" 
 --  Client - MainModule:23

code-
modulescript

local module = {}
function module.update(viewmodel, dt)
	viewmodel.HumanoidRootPart.CFrame = game.Workspace.Camera.CFrame
end

function module.weldgun(gun)
	local Main = gun.Components.Handle
	
	for i, v in ipairs(gun:GetDescendants()) do
		if v:IsA("BasePart") and v ~= Main then
			local newMotor = Instance.new("Motor6D")
			newMotor.Name = v.Name
			newMotor.Part0 = Main
			newMotor.Part1 = v
			newMotor.C0 = newMotor.Part0.CFrame:inverse() * newMotor.Part1.CFrame
			newMotor.Parent = Main
		end
	end
end

function module.equip(viewmodel, gun)
	local gunHandle = gun.Components.Handle
	local HRP_Motor6D = viewmodel:WaitForChild("HumanoidRootPart").Handle
	
	gun.Parent = viewmodel
	HRP_Motor6D.Part1 = gunHandle
end
return module

local script-

local GunModel = game.ReplicatedStorage:WaitForChild("MP5")
local Viewmodel = game.ReplicatedStorage:WaitForChild("Viewmodel")

local mainModule = require(game.ReplicatedStorage.MainModule)

Viewmodel.Parent = game.Workspace.Camera

game:GetService("RunService").RenderStepped:Connect(function(dt)
	print("running")
	mainModule.update(Viewmodel, dt)
	mainModule.weldgun(GunModel)
	mainModule.equip(Viewmodel, GunModel)
	print("finished running")
end)
5 Likes

Make sure your viewmodel’s HRP has an empty Motor6D called ‘Handle’

image

Part 0 = HumanoidRootPart
Part 1 = nil

9 Likes

For making this into a tool and making multiple guns, would it just be as simple and renaming the handler and module script to the gunname+handler/module and turning them off an on depending on if the player has equipped the tool?

2 Likes

Module scripts shouldn’t be replicated for a single tool, they should be kept in ReplicatedStorage. Turning this system into a tool based system isn’t easy. I’d also recommend you just use only 1 Handler. With this you have to constantly check what gun is the player holding and if they equipped the tool. If you want an easier way to implement it I’d just recommend you look at other Community Tutorials because it can get a bit complex when trying to do this but it is very do-able.

3 Likes

Well part 2 is finally out, check it out here. :wink:

4 Likes

Oh god, I didn’t notice this:

image

You only equip and weld the gun once, you don’t need to do it for every frame. So instead it should be like this:

mainModule.weldgun(GunModel)
mainModule.equip(Viewmodel, GunModel)

game:GetService("RunService").RenderStepped:Connect(function(dt)
	mainModule.update(Viewmodel, dt)
end)

I apologize for not noticing!

3 Likes

Dont worry about it, I ended up looking at the end of your scripts and realizing my mistake

1 Like

So I got an error in the module script, I don’t know why, here is the error:

Screenshot 2021-05-04 143500

Here is the module script so far:



local MainModule = {}

function MainModule.Update(viewmodel, dt)
	viewmodel.HumanoidRootPart.CFrame = workspace.Camera.CFrame
end

function MainModule.weldgun(gun)
	local Main = gun.GunComponets.Handle
	
	for i,v in ipairs(gun:GetDescendants()) do
		if v:IsA("BasePart") and v ~= Main then
			local newMotor = Instance.new("Motor6D")
			newMotor.Name = v.Name
			newMotor.Part0 = Main
			newMotor.Part1 = v
			newMotor.C0 = newMotor.Part0.CFrame:inverse() * newMotor.Part1.CFrame
			newMotor.Parent = Main
		end
	end
end

function MainModule.equip(viewmodel, gun, hold)
	local GunHandle = gun.GunComponets.Handle
	local HRP_Motor6D = viewmodel:WaitForChild("HumanoidRootPart").Handle
	
	gun.Parent = viewmodel
	HRP_Motor6D.Part1 = GunHandle
	
	local Hold = viewmodel.AnimationController:LoadAnimation(hold)
	Hold:Play()
end

function MainModule.cast(gun,endposition,velocity)
	local GunBarrel = gun.GunComponets.Barrel
	
	local Bullet = Instance.new("Part")
	Bullet.Size = Vector3.new(1,1,5)
	Bullet.Anchored = true
	Bullet.CanCollide = false
	Bullet.Color = Color3.fromRGB(255,255,255)
	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)
		if (Bullet.Position - GunBarrel.Position).magnitude > 1000 then
			Bullet:Destroy()
			Loop:Disconnect()
		end
	end)
end


return MainModule

Here is the line of code that the error goes to:

Bullet.CFrame = CFrame.new(GunBarrel.Position, endposition)

I don’t know why it’s like this, it’s exactly the same in your code.

1 Like

Hey! Sorry for not responding (i was at school), but make sure your “endposition” is a Vector3.

1 Like

I guess we live in very different time zones, but I fixed that issue, but the bullet doesn’t spawn at the current position of the barrel, I don’t know why, it doesn’t even spawn at the barrel, it just spawns in the middle of your screen.

Can you make sure that the barrel is in the correct position? If it spawns in the middle of the space that means the barrel is in an incorrect position.

Here is the link to my the topic I made just to figure out this issue: topic

Here is an image of the barrel’s position:

Screenshot 2021-05-05 084841
You can barely see the barrel, and still it’s not in the center of the screen. I made a video of shooting the gun, but the file was too big somehow.

Also I noticed that part 2 doesn’t have aiming and reloading, a part 3 would be amazing.

This is where the bullet spawns also:
Screenshot 2021-05-05 091320

If possible, could you provide an rbxm file of the module script for this part?

1 Like

A video would be much better for me to understand but for now all I could recommend is to print() the barrel’s position and the camera’s position (since you said the bullet were spawning in the middle of your screen). And also try doing this after the CFrame.new(barrel.Position, endposition):
Bullet.Position = barrel.Position

Regarding about aiming in reloading, I already gave a statement about aiming here and I won’t be doing a reloading tutorial since it’s very simple.

Update: ok so mid way writing this you editted your post and it looks like the bullet is spawning at 0, 0, 0 (correct me if im wrong). but still try the possible solution above

2 Likes

Yeah I don’t know why it spawns at 0,0,0, but it just does. Also, I used 60 velocity, like you did in your gun, but it moves way faster than your gun. Also reloading is already kind of simple, so I could probably do it myself.

That’s because I forgot to do dt * 60. I updated the script but I didn’t update the video.

Here is what I said in Part 2:

image

1 Like

I printed the position of the bullet, spawns at 0,0,0. I did some extra testing, but nothing else important came up.

Do this also, this way we know if the bullet is spawning to actually positioning to the right position.

And also this.

I did print the barrels position, it’s fine. I modified the module to set the bullets position to the barrel, it works, but after 5-7 seconds, the bullet disappears. The bullet’s position isn’t 0,0,0 anymore, even when the bullet doesn’t appear.

Could you make a video showing this or instead make the game public so I can see the problem myself