Im trying to make a textbox where it plays catalog animation bundle

I have no idea on how to replace specific bundle animation to replace each default animation i am using.

local prompt = gui.TextBox

prompt.FocusLost:Connect(function(enterPressed)
	if enterPressed then
		local animationId = prompt.Text
		if tonumber(animationId) then
			game:GetService("InsertService"):LoadAsset(animationId).Parent = workspace
			if Player then
				repeat wait() until Player.Character
				local animate = Player.Character:FindFirstChild("Animate")
				
			end
		end
	end
end)

What I am trying to achieve is to check each animation in Animate if it’s a expected animation. Let’s say I have this knight walk animation (2) Knight Walk - Roblox
I want to check if this is a walk animation or not. If it’s an walking/running animation then it replace my default walking animation. How do I?

The easiest method that comes to mind would be through the use of HumanoidDescription. This way, Roblox does a lot of the work for you.

The HumanoidDescription of the player is modified so that the animations are of those that the Knight Animation uses.

There are two approaches for this:

I tend to prefer the first one, but either approach would work. As a sample for the code that you have provided, what you could do is:

local prompt = gui.TextBox
local AvatarEditorService = game:GetService('AvatarEditorService')
local AnimationTypes = {"IdleAnimation", "WalkAnimation", "JumpAnimation", "FallAnimation", "ClimbAnimation", "RunAnimation", "SwimAnimation"}

prompt.FocusLost:Connect(function(enterPressed)
	if enterPressed and Player then
		local animationId = tonumber(prompt.Text)
		if animationId then
			local Character: Model = Player.Character -- or Player.CharacterAdded:Wait() Removed as it is best to only accept a request when a Character is already present.
			local Humanoid: Humanoid = Character:WaitForChild('Humanoid', 5)
			-- Check if Humanoid is present and appearance is loaded.
			if Humanoid and Player:HasAppearanceLoaded() then
				local assetDetails = pcall(AvatarEditorService.GetItemDetails, AvatarEditorService, animationId, Enum.AvatarItemType.Asset)
				if assetDetails and table.find(AnimationTypes, assetDetails.AssetType) then
					-- Fetch description
					local Description: HumanoidDescription = Humanoid:GetAppliedDescription()
					
					-- Use AssetType as a key for properties in HumanoidDescription to check if animationId is the same. if this does not work, resort to if statements.
					if Description[assetDetails.AssetType] ~= animationId then
						-- Change property to match animation Id.
						Description[assetDetails.AssetType] = animationId
						-- Cache old description to :Destroy later.
						local OldDescription = Humanoid:FindFirstChild('HumanoidDescription')
						
						-- Reapply description (It can fail if Humanoid is not in the DataModel anymore, so wrap in pcall)
						pcall(Humanoid.ApplyDescription, Humanoid, Description)
						
						-- Dispose of old description
						if OldDescription then
							OldDescription:Destroy()
						end
					end

					-- Dispose of description. (It is no longer useful)
					Description:Destroy()
				end
			end
		end
	end
end)

In this simple sample, I have modified your code to fit the second approach. The first approach is quite similar to this in terms of description modification. In this, AvatarEditorService:GetItemDetails() is used to fetch information about the asset Id provided. The AssetType key can be used to check if the AssetType is an animation. Then, you can check the description to see if the animation ID is any different. You can modify the Id of the animation directly through the HumanoidDescription and reapply it to the Humanoid. The Id of the animation can be the product page as HumanoidDescription handles the rest of the asset management.

I have also removed the repeat that would wait for a character. If the user makes a request, it should not be accepted when the Character is not there yet.

I have left some comments in there in hopes that the approach is understandable. If there is any concern or questions, please feel free to ask! As you can tell I am kind of passionate about HumanoidDescription as an experience I develop for has made extensive use of those in the past year.

1 Like

What is the :AppearanceLoaded() function and how it is used for? And I think there is something wrong with the pcall function that cause the error : attempt to index boolean with ‘AssetType’
I tried to figure it out but im not really understand

I apologize for the mistake. I did not run this before sending it. The reason you are getting a boolean from the pcall is because pcall returns boolean and the result and I happened to forget to account for that Here is the corrected code.

local prompt = gui.TextBox
local AvatarEditorService = game:GetService('AvatarEditorService')
local AnimationTypes = {"IdleAnimation", "WalkAnimation", "JumpAnimation", "FallAnimation", "ClimbAnimation", "RunAnimation", "SwimAnimation"}

prompt.FocusLost:Connect(function(enterPressed)
	if enterPressed and Player then
		local animationId = tonumber(prompt.Text)
		if animationId then
			local Character: Model = Player.Character -- or Player.CharacterAdded:Wait() Removed as it is best to only accept a request when a Character is already present.
			local Humanoid: Humanoid = Character:FindFirstChild('Humanoid')
			-- Check if Humanoid is present and appearance is loaded.
			if Humanoid and Player:HasAppearanceLoaded() then
				local s, assetDetails = pcall(AvatarEditorService.GetItemDetails, AvatarEditorService, animationId, Enum.AvatarItemType.Asset)
				if s and assetDetails and table.find(AnimationTypes, assetDetails.AssetType) then
					-- Fetch description
					local Description: HumanoidDescription = Humanoid:GetAppliedDescription()
					
					-- Use AssetType as a key for properties in HumanoidDescription to check if animationId is the same. if this does not work, resort to if statements.
					if Description[assetDetails.AssetType] ~= animationId then
						-- Change property to match animation Id.
						Description[assetDetails.AssetType] = animationId
						-- Cache old description to :Destroy later.
						local OldDescription = Humanoid:FindFirstChild('HumanoidDescription')
						
						-- Reapply description (It can fail if Humanoid is not in the DataModel anymore, so wrap in pcall)
						pcall(Humanoid.ApplyDescription, Humanoid, Description)
						
						-- Dispose of old description
						if OldDescription then
							OldDescription:Destroy()
						end
					end

					-- Dispose of description. (It is no longer useful)
					Description:Destroy()
				end
			end
		end
	end
end)

As for your question, I assume you are referring to Player:HasAppearanceLoaded(). As mentioned by the documentation, it returns whether the appearance has been loaded on the current avatar. This refers to things like accessories and clothing and any other customization. You can choose to disinclude this if you would like.

Additionally, I have changed getting the humanoid from WaitForChild to FindFirstChild, following the same mentality as to only service users who have loaded avatars.

Is there any way to know if the new animation I redeem in the textbox made changes or not? I tried to print it out but its all fine.
I put the vampire walk id in the textbox (1113741192) but it doesn’t seem to work.
I am pretty sure that the vampire walk id are valid as in (2) Vampire Walk - Roblox .

You can check the HumanoidDescription insyance under Humanoid and see if the animation ids were updated.

Is this on a localscript? If so, clients can only apply descriptions to humanoids that are not controlled by the server. Otherwise I am unsure how you are handling this textbox and communication from the client.

Yes, I am handling textbox in local script. To make it work do I need server script for it? I am confuse on how it works

Yes. You would need a server script if you are updating a player’s HumanoidDescription. I would setup a RemoteEvent to handle this.

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