Restructuring code is breaking scripts

I’m trying to make a monkey game.

The problem is I’m trying to clean/restructure my code and everything is starting to not work.

I’m putting my variables into a module so each module can access the general player variables.

Problematic module
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local Variables = require(script.Parent.Variables)

local Animations = ReplicatedStorage.Animations
local ViewModels = ReplicatedStorage.ViewModels
local Components = ReplicatedStorage.Components

local Camera = workspace.CurrentCamera

local Controller = {}
Controller.__index = Controller

function Controller.new() -- No more here
	local self = setmetatable({},Controller)
	self.Player = Variables.Player
	self.Character = self.Player.Character or self.Player.CharacterAdded:Wait()
	self.Humanoid = self.Character.Humanoid
	self.ViewModel = ViewModels.ViewModel:Clone()
	self.VRoot = self.ViewModel.HumanoidRootPart
	self.ViewModel.Parent = Camera
	self.Animations = {
		VMBanana = self.ViewModel.Humanoid.Animator:LoadAnimation(Animations.VMBanana),
		VMRunning = self.ViewModel.Humanoid.Animator:LoadAnimation(Animations.VMRunning),
		Running = self.Humanoid.Animator:LoadAnimation(Animations.Running),
		Banana = self.Humanoid.Animator:LoadAnimation(Animations.Banana)
	}
	return self
end

function Controller:Init()
	if self.Player.Character.Humanoid.Health == 0 then
		if Camera:FindFirstChild("ViewModel") ~= nil then
			self.ViewModel:Destroy()
		end
	end

	if Camera:FindFirstChild("ViewModel") ~= nil then
		self.ViewModel:PivotTo(Camera.CFrame * CFrame.new(.025, -1.5, -0.5) * CFrame.Angles(0.5, 0, 0))
	end
end

function Controller:Animate()
	if self.Humanoid.MoveDirection.Magnitude <= .01 and self.Animations.Running.IsPlaying == true then
		self.Animations.Running:Stop()
		self.Animations.VMRunning:Stop()
	elseif self.Humanoid.MoveDirection.Magnitude >= .01 and self.Animations.Running.IsPlaying == false then
		self.Animations.Running:Play()
		self.Animations.VMRunning:Play()
	end
end

function Controller:RewardBanana()
	local itemName = self.Player:GetAttribute("Holding") -- for characters
	local itemAnimation = "VM"..itemName -- for viewmodels
	local function Character()
		local itemTrack = self.Animations[itemName]
		itemTrack:Play()
		return itemTrack.Length
	end
	local function ViewModel() -- Viewmodel banana reward needs a motor6d in the hrp and bananamesh in the character,  part0 = hrp, part1 = bananamesh
		local newMesh = Components:FindFirstChild(itemName).Mesh:Clone()
		newMesh.Anchored = false
		newMesh.CastShadow = false
		newMesh.Parent = self.ViewModel
		
		local motor6d = Instance.new("Motor6D")
		motor6d.Part0 = self.VRoot
		motor6d.Part1 = newMesh
		motor6d.Parent = self.VRoot
		local animation = self.ViewModel.Humanoid.Animator:LoadAnimation(Animations[itemAnimation])
		animation:Play()

		task.delay(self.Animations[itemAnimation].Length,function()
			motor6d:Destroy()
			newMesh:Destroy()
		end)
	end
	ViewModel()
	return Character()
end

return Controller

The Variables module does not show the local player as nil yet in the module self.Character and self.Humanoid are still displayed as nil in the output.

There are a bunch of errors, but the one I think that is a sign of whats ruining my code is Property “Animator.EvaluationThrottled” is not currently enabled. (x7)

Looking at the errors, every instance is nil. Why is this happening?

Updated Code
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local Variables = require(script.Parent.Variables)

local Animations = ReplicatedStorage.Animations
local ViewModels = ReplicatedStorage.ViewModels
local Components = ReplicatedStorage.Components

local Camera = workspace.CurrentCamera

local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid = Character.Humanoid
local Root = Character.HumanoidRootPart
local ViewModel = ViewModels.ViewModel:Clone()

ViewModel.Parent = Camera

local AnimationsTable = {
	VMBanana = ViewModel.Humanoid.Animator:LoadAnimation(Animations.VMBanana),
	VMRunning = ViewModel.Humanoid.Animator:LoadAnimation(Animations.VMRunning),
	Running = Humanoid.Animator:LoadAnimation(Animations.Running),
	Banana = Humanoid.Animator:LoadAnimation(Animations.Banana)
}

local Controller = {}

function Controller:Init()
	if Character.Humanoid.Health == 0 then
		if Camera:FindFirstChild("ViewModel") ~= nil then
			ViewModel:Destroy()
		end
	end

	if Camera:FindFirstChild("ViewModel") ~= nil then
		ViewModel:PivotTo(Camera.CFrame * CFrame.new(.025, -1.5, -0.5) * CFrame.Angles(0.5, 0, 0))
	end
end

function Controller:Animate()
	if Humanoid.MoveDirection.Magnitude <= .01 and AnimationsTable.Running.IsPlaying == true then
		AnimationsTable.Running:Stop()
		AnimationsTable.VMRunning:Stop()
	elseif Humanoid.MoveDirection.Magnitude >= .01 and AnimationsTable.Running.IsPlaying == false then
		AnimationsTable.Running:Play()
		AnimationsTable.VMRunning:Play()
	end
end

function Controller:RewardBanana()
	print("3")
	local itemName = Player:GetAttribute("Holding") -- for characters
	local itemAnimation = "VM"..itemName -- for viewmodels
	local function AnimC()
		local itemTrack = AnimationsTable[itemName]
		itemTrack:Play()
		return itemTrack.Length
	end
	local function AnimVM() -- Viewmodel banana reward needs a motor6d in the hrp and bananamesh in the character,  part0 = hrp, part1 = bananamesh
		local newMesh = Components:FindFirstChild(itemName).Mesh:Clone()
		newMesh.Anchored = false
		newMesh.CastShadow = false
		newMesh.Parent = ViewModel
		
		local motor6d = Instance.new("Motor6D")
		motor6d.Part0 = Root
		motor6d.Part1 = newMesh
		motor6d.Parent = Root
		local animation = ViewModel.Humanoid.Animator:LoadAnimation(Animations[itemAnimation])
		animation:Play()

		task.delay(AnimationsTable[itemAnimation].Length,function()
			motor6d:Destroy()
			newMesh:Destroy()
		end)
	end
	AnimVM()
	return AnimC()
end

return Controller

This new code has no errors but whenever I try to eat my banana, my character slides off the map.

I also get the error “Humanoid is not a valid member of Model “ViewModel”” when I try to press E to eat a banana after dying.

edit: nevermind thats because self.Player is nil I think so that might be issue related to Variables modulescript - just like on the screenshot you provided “attempt to index nil with Character” and that means self.Player is equal to nil

local Variables = require(script.Parent.Variables)

try printing out self.Player like this

function Controller:Init()
	
	print(self.Player,"- player")
	
	if self.Player.Character.Humanoid.Health == 0 then
		if Camera:FindFirstChild("ViewModel") ~= nil then
			self.ViewModel:Destroy()
		end
	end

	if Camera:FindFirstChild("ViewModel") ~= nil then
		self.ViewModel:PivotTo(Camera.CFrame * CFrame.new(.025, -1.5, -0.5) * CFrame.Angles(0.5, 0, 0))
	end
end

self.Player is equal to nil in the 1st module(Unupdated).

I found a portion of the issue.

In a module I had called RenderSteps. I had required the Controller Module without saying require(script.Parent.Controller) + .new() at the end.

I added it into the code and I have no more red errors but I’m still sliding off the map, any ideas?

1 Like