Character Pet System

Hello, Im making a pet system but instead of PETS, im using characters.

I was succesfully able to make the character follow the player and everything BUT
I couldnt make two things:

  1. Characters will play a RUNNING animation when the character is moving
  2. Characters will play a IDLE animation when the character isnt moving

below is the Script which i used for the character movements, Could you help me achieve the 2 things i need?

local PetFolder = game.Workspace.petsCharactersFolder
local Spacing = 5
local PetSize = 3
local MaxClimbHeight = 6

local RayParams = RaycastParams.new()
local RayDirection = Vector3.new(0, -500, 0)

local function RearrangeTables(Pets, Rows, MaxRowCapacity)
	table.clear(Rows)
	local AmountOfRows = math.ceil(#Pets)
	for i = 1, AmountOfRows do
		table.insert(Rows, {})
	end
	for i, v in pairs(Pets) do
		local Row = Rows[math.ceil(i / MaxRowCapacity)]
		table.insert(Row, v)
	end
end

local function GetRowWidth(Row, Pet)
	if Pet ~= nil then
		if Pet.PrimaryPart == nil then
			return
		end
		
		local SpacingBetweenPets = Spacing - Pet.PrimaryPart.Size.X
		local RowWidth = 0
		
		if #Row == 1 then
			return 0
		end
		
		for i, v in Row do
			if i ~= #Row then
				RowWidth += Pet.PrimaryPart.Size.X + SpacingBetweenPets
			else
				RowWidth += Pet.PrimaryPart.Size.X
			end
		end
		
		return RowWidth
	end
end

local Camera = game:GetService("Workspace").CurrentCamera

game:GetService("RunService").Heartbeat:Connect(function(DeltaTime)
	for _, petsfol in pairs(PetFolder:GetChildren()) do
		local character = game.Players:FindFirstChild(petsfol.Name).Character; if not character then continue end	
		local HumanoidRootPart = character:WaitForChild("HumanoidRootPart"); if not HumanoidRootPart then continue end
		local Humanoid = character:WaitForChild("Humanoid"); if not Humanoid then continue end

		local petsTable = {}
		local Rows = {}
		
		for _, v in pairs(petsfol:GetChildren()) do
			table.insert(petsTable, v)
		end
		
		RayParams.FilterDescendantsInstances = {PetFolder, character}
		local MaxRowCapacity = math.ceil(math.sqrt(#petsTable))
		RearrangeTables(petsTable, Rows, MaxRowCapacity)
		for i, pet in pairs(petsTable) do
			local RowIndex = math.ceil(i / MaxRowCapacity)
			local Row = Rows[RowIndex]
			local RowWidth = GetRowWidth(Row, pet)

			local Xoffset = #Row == 1 and 0 or RowWidth/2 - pet.PrimaryPart.Size.X/2
			local X = (table.find(Row, pet) - 1) * Spacing
			local Z = RowIndex * Spacing
			local Y = 0

			local RayResult = workspace:Blockcast(pet.PrimaryPart.CFrame + Vector3.new(0, MaxClimbHeight, 0), pet.PrimaryPart.Size, RayDirection, RayParams)

			if RayResult then
				if pet:FindFirstChild("Humanoid") == nil then
					Y = (RayResult.Position.Y + pet.PrimaryPart.Size.Y/2) + 2.5
				else
					Y = (RayResult.Position.Y + pet.PrimaryPart.Size.Y/2) + 1.5
				end
			end

			local TargetCFrame = CFrame.new(HumanoidRootPart.CFrame.X, 0, HumanoidRootPart.CFrame.Z) * HumanoidRootPart.CFrame.Rotation * CFrame.new(X - Xoffset, Y, Z)

			pet.PrimaryPart.CFrame = pet.PrimaryPart.CFrame:Lerp(TargetCFrame, 0.1)
		end
	end
end)
2 Likes

Now, I do not know this will fix but there are 3 ways you can do this:

1.Humanoid.Running event

Now, this event allow you to access speed of current humanoid what you can do is check speed of
humanoid however problem is this event is not too much good to use.

2.Humanoid.MoveDirection

Since you are using .heartbeat you can check state better all you need to do is check player’s character MoveDirection and check if value is higher than 0 if it is this means character is running so you can apply animation to Pets. If it is 0 this means player’s character is idle not moving.

Or option 3 is checking state of humanoid. I hope this helps.

1 Like

The option 2 sounds like an Perfect solution for this!

1 Like

It helped me too although I’m not making a pet simulator game.

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