AnimationTrack not being returned by BindableFunction (Client-side)

Currently, I use a BindableFunction to locally load animations onto my viewmodel (A clone of a player’s character). I mostly use this Bindable to load gun animations. This solution worked up until a point in which it stopped working for reason’s I’ve yet to figure out.

The issue is that the AnimationTrack that is meant to be returned from the Bindable function is returning ‘nil’ to the gun script every single time. This is obviously unintended and breaks my game when this happens. From the Viewmodel’s perspective, it’s a loaded AnimationTrack. After it gets returned through the BindableFunction, GunScript_Local just sees nil and then breaks. This image explains what it looks like from my perspective:

I searched through google and the Devforum directly, and either I am lazy or there was truly no good results out of the 15 somewhat relevant pages I clicked on. I’ve tried to print along the way to diagnose the problem but I’ve yet to figure out a solution.

The Code Part

GunScript_Local Code

the variables and functions before-hand

local animsPreloaded = false

local Animations	= {
	IdleAnim		= handle:WaitForChild("IdleAnim"),
	ShootAnim		= handle:WaitForChild("ShootAnim"),
	ReloadAnim		= handle:WaitForChild("ReloadAnim"),
	ChamberAnim		= handle:WaitForChild("ChamberAnim"),
	VIdleAnim		= handle:WaitForChild("VIdleAnim"),
	VShootAnim		= handle:WaitForChild("VShootAnim"),
	VReloadAnim		= handle:WaitForChild("VReloadAnim"),
	VChamberAnim	= handle:WaitForChild("VChamberAnim")
}
local AnimTracks	= {}

function LoadAnimation(animation: string, priority: Enum.AnimationPriority): AnimationTrack
	pcall(function()
		local animtrack
		if config[animation] ~= 0 then
			animtrack = GF:LoadAnimation(Animations[animation], hum, {Priority = priority}) -- just my way of loading animations. it works
		end
		
		return animtrack
	end)
end

function LoadViewmodelAnimation(animation: string, priority: Enum.AnimationPriority): AnimationTrack
	pcall(function()
		local animtrack
		if config[animation] ~= 0 then
			animtrack = vmFB:Invoke("LoadAnim", Animations[animation]) -- this is what is returning nil
			animtrack.Priority = priority
		end
		
		return animtrack
	end)
end

The part that brings the animations to the gun

if not animsPreloaded then
	AnimTracks = {
		["IdleA"] = LoadAnimation("IdleAnim", Enum.AnimationPriority.Action),
		["ShootA"] = LoadAnimation("ShootAnim", Enum.AnimationPriority.Action4),
		["ReloadA"] = LoadAnimation("ReloadAnim", Enum.AnimationPriority.Action4),
		["ChamberA"] = LoadAnimation("ChamberAnim", Enum.AnimationPriority.Action4),
		["VIdleA"] = LoadViewmodelAnimation("VIdleAnim", Enum.AnimationPriority.Action),
		["VShootA"] = LoadViewmodelAnimation("VShootAnim", Enum.AnimationPriority.Action4),
		["VReloadA"] = LoadViewmodelAnimation("VReloadAnim", Enum.AnimationPriority.Action4),
		["VChamberA"] = LoadViewmodelAnimation("VChamberAnim", Enum.AnimationPriority.Action4)
	}
	
	print("AnimTracks\nUnpacked:", table.unpack(AnimTracks), "\nItem Count", GF:n(AnimTracks))
	
	--animsPreloaded = true | this is commented so I could show how it didn't load no matter how many times I attempted in game.
end

Viewmodel Module Code (Client Context)

the part that loads the animations to the viewmodel

function Viewmodel:InsertAnimation(anim: Animation)
	local newAnim = self.ViewmodelAnimations[anim.Name]
	if not newAnim then
		newAnim = modules["GF"]:LoadAnimation(anim, self.Animator)
		self.ViewmodelAnimations[anim.Name] = newAnim
	else
		warn("Animation", anim.Name, "already loaded in viewmodel.")
	end
	
	return newAnim
end

the bindable function invoke part

ViewmodelFunctionB.OnInvoke = (function(action: string, data1, data2, data3, data4)
	self = Viewmodel
	if action == "LoadAnim" then
		return self:InsertAnimation(data1) -- the part to focus on
	elseif action == "GetAnim" then
		local loadedAnimTrack = self.LoadedAnimations[data1]

		if loadedAnimTrack then
			return loadedAnimTrack
		else
			warn("Animation", data1, "not found in viewmodel.")
		end
	elseif action == "PushSpring" then
		Viewmodel.Springs[data1]:shove(data2)
	end
end)

Maybe I’m just dumb, but I really couldn’t figure out why this code wouldn’t work, as I don’t know exactly what I added to make it fail… All help is appreciated. I’m posting this @ 1:56 AM so if I don’t respond in the next 8 hours it’s because I’m sleeping.

When invoking the function you put the action name and animations[animation]. None of the keys in your animation table are strings however, as you made sure the animation param is a string. Do this to each key in your animations table

[“IdleAnim”] — Example for idle anim, copy the format for the rest

The function for when you’re receiving the invoke also has… 4 “data” params? Isn’t there only one value that you’re sending when invoking? Replace all 4 data params with one called “AnimInstance” like this

ViewmodelFunctionB.OnInvoke = (function(action: string, AnimInstance : Animation)

Of course this may not be correct, but I could deduce this much from reading the code

1 Like

I couldn’t get this solution to work (as it technically makes no difference anyway since Luau dictionaries will always try to be strings anyway)… but this was helpful as I took a second look at my code and Behold! - I realized I simply wasn’t returning anything from LoadAnimation() or LoadViewmodelAnimation(), which was pretty much because my lazy p-call implementation.

For example, this is what the Working code looks like:

function LoadAnimation(animation: string, priority: Enum.AnimationPriority): AnimationTrack
	if config[animation] ~= 0 then
		local success, returned = pcall(GF.LoadAnimation, GF, Animations[animation], hum, {Priority = priority})
		if not success and returned then
			warn("Gun Animation failed to load:", returned)
		end
	
		return returned
	end
end

And now it’s very obvious why I should read twice before coming to the devforum. Anyway, Thanks for your help!

edit: tuned the working LoadAnimation snippet to be more compact

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