Play animations on character who's CFrame is constantly being updated

Hello, I’m currently creating a camera video screen on a SurfaceGui using a ViewportFrame and a WorldModel. My goal is to be able to display players on the UI in real-time with their animations playing as well. I’ve been successful in putting player’s characters on the screen and keeping their positions updated constantly by changing their CFrame. The only issue is the animations, I’m not sure how to go about playing the animations, every time I try to load an animation on the character in the ViewportFrame the animation keeps getting reset every time their CFrame changes, which is every 1/25 of a second.

So, I’d like to be able to play animations on the characters, is there any way to achieve this? Thanks.

I’ll provide my code in case that helps anyone understand what I’ve got going on.

Server:

local ScreenRefreshRate = 1/25 -- Seconds

local Players = game:GetService("Players")
local folderScreenDetection = workspace.ScreenDetection
local remoteScreenUpdate = game:GetService("ReplicatedStorage").ScreenUpdate
local remoteScreenUnrender = game:GetService("ReplicatedStorage").ScreenUnrender
local screenData = {}

-- Find and remove player from screenData dictionary
local function removePlayerFromData(plr)
	screenData[plr.Name] = nil
	print("Removed:")
	print(screenData)
end

-- Add player to screenData dictionary
local function addPlayerToData(plr)
	screenData[plr.Name] = plr.Character.HumanoidRootPart.CFrame
	print("Added:")
	print(screenData)	
end

-- Check if player is in screenData dictionary
local function isPlayerInData(plr)
	for i, v in pairs(screenData) do 
		if i == plr.Name then return true end
	end
	return false
end

-- Detect when player enters the stage, if they're not already in the screenData dictionary, add them
local function playerEntered(plr)
	if not isPlayerInData(plr) then 
		addPlayerToData(plr)
	end
end

-- Detect when player leaves the stage, if they're in the screenData dictionary, remove them and fire the Unrender Remote
local function playerExited(plr)
	if isPlayerInData(plr) then
		removePlayerFromData(plr)
		remoteScreenUnrender:FireAllClients(plr.Name)
	end
end

-- Connecting the playerEntered and playerExited event to a Touched event
for i, v in ipairs(folderScreenDetection:GetChildren()) do
	if v.Name == "Enter" then
		for i, v in ipairs(v:GetChildren()) do
			v.Touched:Connect(function(p)
				
				local c = p:FindFirstAncestorOfClass("Model")
				local plr = Players:GetPlayerFromCharacter(c)
				
				if c and plr then
					playerEntered(plr)
				end
			end)
		end
	else
		for i, v in ipairs(v:GetChildren()) do
			v.Touched:Connect(function(p)	
				local c = p:FindFirstAncestorOfClass("Model")
				local plr = Players:GetPlayerFromCharacter(c)
				if c and plr then
					playerExited(plr)
				end	
			end)
		end
	end
end

-- Constantly update all player's positions in the screenData dictionary and send it to the client
local screenUpdate = coroutine.wrap(function()
	while true do
		wait(ScreenRefreshRate)
		
		-- get players position and keep it updated in data dictionary
		for key, value in pairs(screenData) do	
			local playerPosition = Players:FindFirstChild(key).Character.HumanoidRootPart.CFrame
			screenData[key] = playerPosition
		end
		
		-- send to client
		remoteScreenUpdate:FireAllClients(screenData)
	end
end)()

Client (Animations)

local remoteScreenDetection = game:GetService("ReplicatedStorage"):WaitForChild("ScreenUpdate")
local remoteScreenUnrender = game:GetService("ReplicatedStorage"):WaitForChild("ScreenUnrender")
local Players = game:GetService("Players")
local worldModel = script.Parent:WaitForChild("WorldModel")

local runningAnim = Instance.new("Animation")
local idleAnim = Instance.new("Animation")
local sitAnim = Instance.new("Animation")
local jumpAnim = Instance.new("Animation")
runningAnim.Name = "Run"
idleAnim.Name = "Idle"
sitAnim.Name = "Sit"
jumpAnim.Name = "Jump"
runningAnim.AnimationId = "http://www.roblox.com/asset/?id=10921076136"
idleAnim.AnimationId = "http://www.roblox.com/asset/?id=10921071918"
sitAnim.AnimationId = "http://www.roblox.com/asset/?id=2506281703"
jumpAnim.AnimationId = "http://www.roblox.com/asset/?id=10921078135"

local function checkIfPlayerIsInWorldModel(name)
	if worldModel:FindFirstChild(name) then return true end
end

local function removePlayerFromWorldModel(name)
	if checkIfPlayerIsInWorldModel(name) then
		worldModel:FindFirstChild(name):Destroy()
	end
end

local function addPlayerToWorldModel(name)
	
	print(workspace:FindFirstChild(name))
	local clonedCharacter = workspace:FindFirstChild(name):Clone()
	print(clonedCharacter)
	clonedCharacter.Parent = worldModel
	
end

-- ANIMATIONS??
local function updatePlayerInWorldModel(key, value)
	
	worldModel:FindFirstChild(key):WaitForChild("HumanoidRootPart").CFrame = value
	
	local WMcharacter = worldModel:FindFirstChild(key)
	local WMhumanoid = WMcharacter:FindFirstChild("Humanoid")
	local currentAnimation = WMhumanoid:GetPlayingAnimationTracks()
	if WMhumanoid then
		
		
		
		local animator = WMhumanoid:FindFirstChildOfClass("Animator")
		local animation = animator:LoadAnimation(runningAnim)
		animation:Play()
		animation.Looped = true
		
	end
	
	
	
end

-- Every frame the server fires this event to all clients with data from all players in the screen's range
remoteScreenDetection.OnClientEvent:Connect(function(data)
	
	for key, value in pairs(data) do
		if not checkIfPlayerIsInWorldModel(key) then
			addPlayerToWorldModel(key)
		else
			updatePlayerInWorldModel(key, value)
		end
	end
	
	--print(data)

end)

remoteScreenUnrender.OnClientEvent:Connect(removePlayerFromWorldModel)

I decided to move my entire system to the client and decided to try changing each individual limb’s CFrame instead of trying to play animations and it worked.

Wow, this looks very complicated SneakyRocket575. I wish I could help you but due to my lack of scripting knowledge, I can neither help or forward you to someone who can help you. Once again I am very sorry SneakyRocket575 but I am not a scripter.

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