Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
1

Why is my script not recognising this as a function?

Asked by 3 years ago

Hello! So, I'm currently developing a system for my trains to move with, but I've ran into a sort of dead end.

Basically, whenever I call the :TweenCarriages() function, it just throws an error: attempt to call nil value.

I know it's not a problem with the script that's calling.

local TweenService = game:GetService("TweenService")

local TrainService = {}
TrainService.__index = TrainService

function TrainService.new(trainModel)
    assert(typeof(trainModel) == 'Instance')

    local self = setmetatable({},TrainService)

    self.TrainModel = trainModel
    self.CurrentNode = 1
    self.Carriages = {}
    self.Speed = 0


    return self
end

function TrainService:CreateNewCarriage(carriagePart)
    table.insert(self.Carriages, carriagePart)
    --print(typeof(self.Carriages[1]))
end

function TrainService:CalculateTime(distance, speed)        
    local Time = distance / speed

    return Time
end


function TrainService:TweenCarriage(tweenTime, nextNode, lastNode, carriageNumber)
    if not assert(typeof(nextNode) == "Instance" and nextNode:IsA("BasePart"), "nextNode must be a BasePart") then return end
    if not assert(typeof(lastNode) == "Instance" and lastNode:IsA("BasePart"), "lastNode must be a BasePart") then return end
    if not assert(tonumber(tweenTime), "tweenTime must be a Number") then return end

    local info = TweenInfo.new(
        tweenTime,
        Enum.EasingStyle.Linear,
        Enum.EasingDirection.InOut,
        0, -- RepeatCount (-1 = Infinite)
        false, -- Reverse tween after finishing
        0 -- DelayTime
    )

    local rot = nextNode.Rotation
    local rotY = nil

    local dotProduct = self.Carriages[carriageNumber].CFrame.LookVector:Dot(nextNode.CFrame.LookVector)

    if (dotProduct > 0.75) then
        rotY = nextNode.Rotation.Y
        -- Do something with dotY
    elseif (dotProduct < -0.75) then
        rotY = nextNode.Rotation.Y+180
        -- Do something else with rotY
    else
        rotY = nextNode.Rotation.Y
        warn("An issue has occurred.")
    end

    local position = {CFrame = CFrame.new(nextNode.Position)*CFrame.Angles(math.rad(rot.X),math.rad(rotY),math.rad(rot.Z))}


    local propertyTable = {
        CFrame = nextNode.CFrame
    }

    local tween = TweenService:Create(self.Carriages[carriageNumber],info,position)

    tween:Play()
    tween.Completed:Wait()
end

return TrainService

Any help would be appreciated!

1 answer

Log in to vote
0
Answered by
Yuuwa0519 197
3 years ago

The solution is very easy. Just a typo XD Instead of :TweenCariages, you have the method as :TweenCariage()

Few other things to note. assert() is a standalone function that throws an error when the first parameter is not true, thus wrapping it with if-else (you do this in line 33 to 35) does literally nothing, so u can get rid of that. Secondly, when constructing the self, you should rather wrap all the components within the table rather than indexing them after for optimization (micro).

--Constructor Func Optimization
function TrainService.new(trainModel)
    return setmetatable({
        TrainModel = trainModel,
        CurrentNode = 1,
            Carriages = {},
            Speed = 0
    }, TrainService)
end
Ad

Answer this question