Error "HumanoidRootPart is not a valid member of Model "Viewmodel"?

I’m working on a custom gun system, ad so far it is working fine, but I have ran into a major issue. Upon adding this equip and unequip function to my module script, the console is spammed with the message HumanoidRootPart is not a valid member of Model "Viewmodel" because it is erroring from this code:

function module.update(viewmodel, dt, RecoilSpring, BobbleSpring, SwayingSpring, gun)
	viewmodel.HumanoidRootPart.CFrame = game.Workspace.Camera.CFrame
	
	local MouseDelta = game:GetService("UserInputService"):GetMouseDelta()
	local Character = game.Players.LocalPlayer.Character or game.Players.LocalPlayer.CharacterAdded:Wait()
		
	local UpdatedRecoilSpring = RecoilSpring:update(dt)
	local UpdatedSwaySpring = SwayingSpring:update(dt)
	
	gun.GunComponents.Sight.CFrame = gun.GunComponents.Sight.CFrame:Lerp(viewmodel.HumanoidRootPart.CFrame, game.ReplicatedStorage.Values.AimAlpha.Value)

	viewmodel.HumanoidRootPart.CFrame *= CFrame.new(UpdatedSwaySpring.X, UpdatedSwaySpring.Y, 0)

	
	viewmodel.HumanoidRootPart.CFrame *= CFrame.Angles(math.rad(UpdatedRecoilSpring.X) * 2, 0, 0)
	game.Workspace.Camera.CFrame *= CFrame.Angles(math.rad(UpdatedRecoilSpring.X), math.rad(UpdatedRecoilSpring.Y), math.rad(UpdatedRecoilSpring.Z))
end

which fires every frame. Here is the local code, if needed.

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

Is there something I’m missing, or is it an issue with my code? Please help :slight_smile:

It is hard to tell. You would need to show us where you create the Viewmodel variable that you pass into mainModule.update so we can see the model itself. It would appear whatever model it is does not have a HumanoidRootPart so maybe you are sending in the wrong model?

Well, basically it’s saying that HumanoidRootPart doesn’t exist. I would just change it to PrimaryPart instead. Make sure you have a primarypart though

Ok, so I have a little update…

I have changed the code and it is SO CLOSE to working, but there is one problem:
The gun no longer is attached to the player.
It just doesn’t go into the hands, instead it clones into the original location.
(When I say this, I mean the holding animation isn’t playing correctly)

I have decided to provide the full code as I believe that would make it easier to debug

Module Script

local module = {}

local equipped = false

local function GetBobbing(addition)
	return math.sin(tick() * addition * 1.3) * 0.8
end

function module.viewmodelupdate(viewmodel, dt)
	viewmodel.HumanoidRootPart.CFrame = game.Workspace.Camera.CFrame
end

function module.update(viewmodel, dt, RecoilSpring, BobbleSpring, SwayingSpring, gun)
	viewmodel.HumanoidRootPart.CFrame = game.Workspace.Camera.CFrame
	
	local MouseDelta = game:GetService("UserInputService"):GetMouseDelta()
	local Character = game.Players.LocalPlayer.Character or game.Players.LocalPlayer.CharacterAdded:Wait()
		
	local UpdatedRecoilSpring = RecoilSpring:update(dt)
	local UpdatedSwaySpring = SwayingSpring:update(dt)
	
	if gun then
		gun.GunComponents.Sight.CFrame = gun.GunComponents.Sight.CFrame:Lerp(viewmodel.HumanoidRootPart.CFrame, game.ReplicatedStorage.Values.AimAlpha.Value)

		viewmodel.HumanoidRootPart.CFrame *= CFrame.new(UpdatedSwaySpring.X, UpdatedSwaySpring.Y, 0)


		viewmodel.HumanoidRootPart.CFrame *= CFrame.Angles(math.rad(UpdatedRecoilSpring.X) * 2, 0, 0)
		game.Workspace.Camera.CFrame *= CFrame.Angles(math.rad(UpdatedRecoilSpring.X), math.rad(UpdatedRecoilSpring.Y), math.rad(UpdatedRecoilSpring.Z))
	end
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 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, hold, nothing)
	if equipped then
		return
	end

	local gunHandle = gun.GunComponents.Handle
	local HRP_Motor6D = viewmodel:WaitForChild("HumanoidRootPart").Handle
	
	local gun = gun:Clone()
	
	gun.Parent = viewmodel
	HRP_Motor6D.Part1 = gunHandle

	local Hold = viewmodel.AnimationController:LoadAnimation(hold)
	Hold:Play()

	equipped = true
end

function module.unequip(viewmodel, gun, anim, hold)
	if not equipped then
		return
	end

	local gunHandle = gun.GunComponents.Handle
	local HRP_Motor6D = viewmodel:WaitForChild("HumanoidRootPart").Handle

	local Hold = viewmodel.AnimationController:LoadAnimation(hold)
	Hold:Stop()

	local newviewmodel = game.Workspace.Viewmodel:Clone()
	newviewmodel.Parent = game.Workspace.CurrentCamera
	viewmodel:Destroy()

	gun.Parent = nil
	HRP_Motor6D.Part1 = nil

	equipped = false
end

function module.cast(origin, endposition, velocity, damage)	
	local Bullet = Instance.new("Part")
	Bullet.Name = "Bullet"
	Bullet.Parent = workspace.Bullets
	Bullet.Size = Vector3.new(1,1,3)
	Bullet.Anchored = true
	Bullet.CanCollide = false
	Bullet.Color = Color3.new(0.933333, 0.803922, 0.0117647)
	Bullet.Material = Enum.Material.Metal

	Bullet.CFrame = CFrame.new(origin, endposition)
	
	local Loop

	Loop = game:GetService("RunService").RenderStepped:Connect(function(dt)
		Bullet.CFrame *= CFrame.new(0, 0, -velocity * (dt * 60))
		if (Bullet.Position - origin).magnitude > 5000 then
			Bullet:Destroy()
			Loop:Disconnect()
		end
		
		local Hit = workspace:Raycast(Bullet.Position, Bullet.CFrame.LookVector * velocity * 1.5)

		if Hit then

			if Hit.Instance.Parent:FindFirstChild("Humanoid") and damage ~= nil then
				game.ReplicatedStorage:WaitForChild("Damage"):FireServer(Hit.Instance.Parent, 10)
				print("bullet from "..game.Players.LocalPlayer.Name.." hit a player i guess")
			else
				print("bullet hit a wall")
				Loop:Disconnect()
				Bullet:Destroy()
			end
		end

	end)
end

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

	end
end

function module.GetMouse(Distance, CastParams)
	local MouseLocation = game:GetService("UserInputService"):GetMouseLocation()
	local UnitRay = game:GetService("Workspace").Camera:ViewportPointToRay(MouseLocation.X, MouseLocation.Y)
	
	local origin = UnitRay.Origin
	local endp = UnitRay.Direction * Distance
	local Hit = game:GetService("Workspace"):Raycast(origin, endp, CastParams)
	
	if Hit then
		return Hit.Position
	else
		return UnitRay.Origin + UnitRay.Direction * Distance
	end
end

function module.reload(viewmodel, reloadAnim)
	print("module recieved request to reload")
	local reload = viewmodel.AnimationController:LoadAnimation(reloadAnim)
	reload.Looped = false
	reload:Play()
	reload.Stopped:Wait()
	print("reloaded")
	return 30
end
	
	
return module

Local Script

local GunModel = game.ReplicatedStorage:WaitForChild("FN Scar")
local Viewmodel = game.ReplicatedStorage:WaitForChild("Viewmodel"):Clone()
local AnimFolder = game.ReplicatedStorage:WaitForChild("ScarAnimations")
local mainModule = require(game.ReplicatedStorage.MainModule)
local SpringModule = require(game.ReplicatedStorage.SpringModule)
local IsPlayerHoldingMouse
local CanFire = true
local Delay = 0.1
local RecoilSpring = SpringModule.new()
local BobbleSpring = SpringModule.new()
local SwayingSpring = SpringModule.new()
local Fire = game.ReplicatedStorage:WaitForChild("Fire")
local equipped = false
local AmmoAmount = 30

Viewmodel.Parent = game.Workspace.Camera

mainModule.weldgun(GunModel)

game:GetService("RunService").RenderStepped:Connect(function(dt)
	Viewmodel = game.Workspace.Camera.Viewmodel
	if GunModel then
		mainModule.update(Viewmodel, dt, RecoilSpring, BobbleSpring, SwayingSpring, GunModel)
	else
		mainModule.viewmodelupdate(Viewmodel, dt)
	end
end)

game:GetService("UserInputService").InputBegan:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 and equipped == true then
		IsPlayerHoldingMouse = true
	elseif input.UserInputType == Enum.UserInputType.MouseButton2 and equipped == true then
		mainModule.aim(true, Viewmodel, GunModel)
	elseif input.KeyCode == Enum.KeyCode.One then
		if not equipped then
			mainModule.equip(Viewmodel, GunModel, AnimFolder.Hold, AnimFolder.Nothing)
			equipped = true
		else
			mainModule.unequip(Viewmodel, GunModel, AnimFolder.Nothing, AnimFolder.Hold)
			equipped = false
		end
	end
end)

game:GetService("UserInputService").InputEnded:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 and equipped == true then
		IsPlayerHoldingMouse = false
		
	elseif input.UserInputType == Enum.UserInputType.MouseButton2 and equipped == true then
		mainModule.aim(false, Viewmodel, GunModel)
		
	elseif input.KeyCode == Enum.KeyCode.R and equipped == true then 
		print(game.Players.LocalPlayer.Name.." reloaded")
		AmmoAmount = mainModule.reload(Viewmodel, AnimFolder.Reload)
	end
end)

game:GetService("RunService").Heartbeat:Connect(function(dt)
	if IsPlayerHoldingMouse then
		if CanFire and AmmoAmount > 0 then
			AmmoAmount -= 1
			CanFire = false
			
			RecoilSpring:shove(Vector3.new(5, 2, 3))
			
			coroutine.wrap(function()
				local FireSound = GunModel.GunComponents.Sounds.Fire:Clone()
				FireSound.Parent = game.Workspace
				FireSound:Play()
				FireSound.Ended:Connect(function()
					FireSound.Parent = nil
					FireSound:Destroy()
				end)
			end)()
			
			coroutine.wrap(function()
				wait(0.2)
				RecoilSpring:shove(Vector3.new(-2.8, math.random(-4, 4), -10))
			end)()
			
			local CastParams = RaycastParams.new()
			CastParams.IgnoreWater = true
			CastParams.FilterType = Enum.RaycastFilterType.Blacklist
			CastParams.FilterDescendantsInstances = {Viewmodel, game.Players.LocalPlayer.Character}
			
			local Mouse = mainModule.GetMouse(1000, CastParams)
			
			mainModule.cast(GunModel.GunComponents.Barrel.Position, Mouse, 5, game.ReplicatedStorage.Damage)
			Fire:FireServer(GunModel.GunComponents.Barrel.Position, Mouse)
			
			wait(0.2)
			CanFire = true
		end
	end
end)

Fire.OnClientEvent:Connect(function(client, origin, endposition)
	if client ~= game.Players.LocalPlayer then
		mainModule.cast(origin, endposition, 5, nil)
	end
end)

Bump because I really need help with this and I’m so close

I’m unfamiliar with viewmodels generally, so I apologise is this is way off, but try checking the module.equip function.
It looks like the HRPmotor6d.part1 is being allocated the original gun.guncomponents.handle instead of the cloned one.

After doing this, it only lets me equip it once then returns to the falling into the ground thing. I wonder if I should change the local script instead of the module script…?

Currently you send the original gun in replicated storage to the module functions from the local script, if you cloned the gun and sent the clone it might solve your referencing problems.
As I think most properties get changed on the original otherwise.
I mean, hold a reference to the clone in the local script ( not clone each time).