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

small question about metatables and method functions... why is it returning nil?

Asked by 4 years ago
animate = {}
animate_mt = {__index = animate}

function animate.new(viewModel)
    local self = {}

    self.AnimPriority1 = false 
    self.AnimPriority2 = false 


    self.AnimControler = Instance.new("AnimationController",viewModel)
    self.IdleAnim = Instance.new("Animation",self.AnimControler)
    self.IdleAnim.Name = "IdleAnimation"
    self.IdleAnim.AnimationId = DefaultAnimPack["idle"] -- idle
    self.RunAnim = Instance.new("Animation",self.AnimControler)
    self.RunAnim.Name = "RunAnimation"
    self.RunAnim.AnimationId = DefaultAnimPack["run"] -- run
    self.AdsAnim = Instance.new("Animation",self.AnimControler)
    self.AdsAnim.Name = "AdsAnimation"
    self.AdsAnim.AnimationId = DefaultAnimPack["ads"]
    self.WR_FrontAnim = Instance.new("Animation",self.AnimControler)
    self.WR_FrontAnim.Name = "WallRunFrontAnimation"
    self.WR_FrontAnim.AnimationId = DefaultAnimPack["wallrun_front"]
    self.WR_RightAnim = Instance.new("Animation",self.AnimControler)
    self.WR_RightAnim.Name = "WallRunRightAnimation"
    self.WR_RightAnim.AnimationId = DefaultAnimPack["wallrun_front"]
    self.WR_LeftAnim = Instance.new("Animation",self.AnimControler)
    self.WR_LeftAnim.Name = "WallRunLeftAnimation"
    self.WR_LeftAnim.AnimationId = DefaultAnimPack["wallrun_left"]

    return setmetatable(self,animate_mt)
end

return animate

i've made a simple function that creates an animation controller and some animations, its all in a module script, but i've made a few methods for animate like:

function animate:StopAllAnimations()
    local ActiveTracks = self.AnimControler:GetPlayingAnimationTracks()
    for _,v in ipairs(ActiveTracks) do
        v:Stop()
    end
end
function animate:LoadAnimations(AnimationPack)

    self.IdleAnim.AnimationId = AnimationPack["idle"]
    self.RunAnim.AnimationId = AnimationPack["run"]
    self.AdsAnim.AnimationId = AnimationPack["ads"]
    self.WR_FrontAnim.AnimationId = DefaultAnimPack["wallrun_front"]
    self.WR_RightAnim.AnimationId = DefaultAnimPack["wallrun_right"]
    self.WR_LeftAnim.AnimationId = DefaultAnimPack["wallrun_left"]

    self.IdleTrack = self.AnimControler:LoadAnimation(self.IdleAnim)
    self.RunTrack = self.AnimControler:LoadAnimation(self.RunAnim)
    self.AdsTrack = self.AnimControler:LoadAnimation(self.AdsAnim)  
    self.WR_FrontTrack = self.AnimControler:LoadAnimation(self.WR_FrontAnim)
    self.WR_RightTrack = self.AnimControler:LoadAnimation(self.WR_RightAnim)
    self.WR_LeftTrack = self.AnimControler:LoadAnimation(self.WR_LeftAnim)
end

but the problem is that these methods for "animate" don't really get self.any variable put in animate, it returns to me that self.IdleAnim / any other self. variable is a nil, even if INSIDE the actual animate.new() function they have a value, the methods don't recieve the self table

example: when i call animate:LoadAnimations(animationpack) it says that self.IdleAnim is nil. i added print(self.IdleAnim) in both animate.new() and animate:LoadAnimations(), animate.new() gives a proper value, but animate:LoadAnimations() has a nil and every other method of animate, they don't get the self table.

is there a problem in my script? if someone could be kind enough, explaining these would help because i'm new into metatables and this kind of functions.

1 answer

Log in to vote
1
Answered by 4 years ago

Your modules are completely fine, you're encountering a different problem:

To begin with, I'm gonna explain what the self parameter really is, and how functions get it

Whenever you call a function from a table(Which we'll call tbl for now), as tbl.MyFunction(), it'll act as normal. However, if you call tbl:MyFunction() instead, lua will actually handle this the same as tbl.MyFunction(tbl), and the tbl parameter that's now added to the function is called self.

So, in your scenario, calling animate.new() will act as a normal function, while animate:LoadAnimations(...) will also pass on the animate table. However, when you're trying to print IdleAnim from self, you´re actually printing it from animate, and animate doesn't have an IdleAnim variable, so it'll print nil, while in animate.new(), self is newly made, and just received the IdleAnim variable, meaning it won´t print nil

Now, the fix to this is quite simple: You must store the result from animate.new() in a new table, which we'll call newanim, and then you must call newanim:LoadAnimations(...) instead. Since newanim doesn't actually have any LoadAnimations index at all, it'll go to the __index metamethod of newanim, which redirects it to animate, and it finds the LoadAnimations in there. Then, it'll call the function, and gives newanim as the self variable, which does actually have the IdleAnim index, meaning that it won't print nil.

Now, to explain the fix in a code block:

-- What you're doing:
animate.new()
animate:LoadAnimations(animationpack)

-- The fix:
local newanim = animate.new()
newanim:LoadAnimations(animationpack)
0
thank you, by the time of response, i have done research and learned about these, but im glad theres somebody willing to take his time and explain in this depth. thank you! Wingboy0 57 — 4y
Ad

Answer this question