Issue with OOP function not recognizing self

I’m creating an advanced train chassis system for a game I’m working on, but for some reason the :_setNextTrack function doesn’t recognize self, and keeps erroring “attempted to index nil with “start””

No idea why this is happening, I’ve checked to make sure the function is called correctly and the spellings match, any help would be massively appreciated because this is driving me insane.

Chassis Module:

local CollectionService = game:GetService("CollectionService")
local RunService = game:GetService("RunService")

local RAIL_ALIGNMENT_TAG = "RailAlignment"

local FORWARD_NAME = "Forward"
local BACKWARD_NAME = "Backward"

local SWITCH_DISTANCE = 0.04
local CONNECT_DISTANCE = 0.02

local Chassis = {}
Chassis.__index = Chassis

function Chassis.new(chassis)
	local self = setmetatable({}, Chassis)
	
	self.Chassis = chassis :: Model
	self.ChassisAttachment = chassis.Chassis.ChassisAttachment :: Attachment
	self.Wheels = chassis.Wheels:GetChildren() :: {HingeConstraint}
	
	local Prismatic, StartAttachment = self:_build()
	
	self.Prismatic = Prismatic
	self.StartAttachment = StartAttachment
	
	
	self.CurrentTrack = nil
	self.TrackDirection = "Forward"
	
	self.Paths = {}
	self.CurrentPath = nil
	self.PathLength = 0
	self.PathNumber = 0
	
	self.PathAttachment = nil
	
	
	self.RunConnection = nil
	
	return self
end

function Chassis:_build() : (PrismaticConstraint, Attachment)
	local Prismatic = Instance.new("PrismaticConstraint")
	Prismatic.Parent = self.Chassis
	Prismatic.LimitsEnabled = true
	Prismatic.UpperLimit = 0
	Prismatic.ActuatorType = Enum.ActuatorType.Motor
	Prismatic.MotorMaxForce = 1000000
	Prismatic.MotorMaxAcceleration = 20

	local StartAttachment = Instance.new("Attachment")
	StartAttachment.Parent = workspace.Terrain
	StartAttachment.Name = "StartChassis"
	StartAttachment.WorldCFrame = self.ChassisAttachment.WorldCFrame

	Prismatic.Attachment0 = StartAttachment
	Prismatic.Attachment1 = self.ChassisAttachment
	
	Prismatic.Velocity = 26

	return Prismatic, StartAttachment
end

function Chassis:_getAlignmentConnects(alignment : Part) : Part
	local params = OverlapParams.new()
	params.FilterType = Enum.RaycastFilterType.Include
	params.FilterDescendantsInstances = CollectionService:GetTagged(RAIL_ALIGNMENT_TAG)
	
	print(alignment)
	
	local connects = workspace:GetPartsInPart(alignment, params)
	
	return connects[1]
end

function Chassis:_setNextTrack()
	local leadAlignment = nil
	
	if self.TrackDirection == "Forward" then
		leadAlignment = self.CurrentTrack.Alignment.End :: Part
	else
		leadAlignment = self.CurrentTrack.Alignment.Start :: Part
	end
	
	local Connected = self:_getAlignmentConnects(leadAlignment)
	if not Connected then return end
	
	if Connected.Name == FORWARD_NAME then
		self:SetTrack(Connected.Name, 1, "Forward")
	else
		self:SetTrack(Connected.Name, 1, "Backward")
	end
end

function Chassis:_updateConstraints()
	if self.Prismatic.CurrentPosition > self.PathLength then
		if self.Paths[self.PathNumber + 1] then
			self:_setPath(self.PathNumber + 1)
		else
			self:_setNextTrack()
		end
	end
end


function Chassis:_setPath(pathNumber : number)
	self.PathNumber = math.clamp(pathNumber, 1, #self.Paths)
	self.CurrentPath = self.Paths[self.PathNumber] :: BasePart
	self.PathLength = self.CurrentPath.Size.Z
	
	if self.TrackDirection == "Forward" then
		self.PathAttachment = self.CurrentPath:FindFirstChild(FORWARD_NAME) :: Attachment
	else
		self.PathAttachment = self.CurrentPath:FindFirstChild(BACKWARD_NAME) :: Attachment
	end
	
	self.StartAttachment.WorldCFrame = self.PathAttachment.WorldCFrame
	self.Prismatic.LowerLimit = SWITCH_DISTANCE
	self.Prismatic.UpperLimit = self.PathLength + SWITCH_DISTANCE
end

function Chassis:SetTrack(track, pathNumber : number, direction : string)
	self.CurrentTrack = track :: Model
	self.TrackDirection = direction
	self.Paths = track.Path:GetChildren() :: {BasePart}
	
	self:_setPath(pathNumber)
	
	self.RunConnection = RunService.Heartbeat:Connect(function()
		self:_updateConstraints()
	end)
end

return Chassis

Test Constructor Script (for those interested):

local Chassis = require(script.Parent.Chassis)

local NewChassis = Chassis.new(workspace.Chassis)
NewChassis:SetTrack(workspace.Track.Start, 1, "Forward")

print(NewChassis)

maybe workspace.start doesnt exist? check if its anchored? seems to be the only thing that could happen

Ill check, but Im pretty sure that isnt the issue. Thing is, self.TrackDirection IS “Forward”, so It shouldn’t even be looking for “Start”, it should be looking for “End”. Only reason it would be looking for Start is if it doesn’t recognize the TrackDirection variable.

Nevermind, issue resolved. Track instance wasn’t set correctly.

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.