Stop Animations regardless of ancestry - Animations only stop when Humanoid/Controller is a descendant of workspace

Apparently when cloning the player’s character and inserting it into a viewportframe, there is no way to manually stop animations except for temporarily parenting them to workspace. I had to place this bit of code within a larger function to avoid situations like these:

After adding that bit, the animation no longer played during importation - since beforehand, I’d directly parent it to the viewport frame, instead of shortly placing it into workspace.

This behavior is unintuitive, I’m posting this so that this can either be documented or changed.

function createviewportmodel(NPC)
	if not NPC then return end
	local PlayerGui = Player:FindFirstChild("PlayerGui")
	local DialogueUI = PlayerGui:FindFirstChild("Dialogue")
	local viewport = DialogueUI.ViewedNPC
	
	local alreadyexistingmodel = viewport:FindFirstChildOfClass("Model")
	if alreadyexistingmodel then
		alreadyexistingmodel:Destroy()
	end
		
	NPC.Archivable = true
	local fake_char = NPC:clone()
		
	if fake_char:FindFirstChild("Humanoid") then
		if PlatformstandToggle then
			local Controller = NPC:FindFirstChildOfClass("Humanoid") or NPC:FindFirstChildOfClass("AnimationController")
			local AnimationTracks = Controller:GetPlayingAnimationTracks()
			
			for i, track in pairs (AnimationTracks) do
				--warn(track)
				track:AdjustWeight(0, 1/60)
				track:Stop(1/60)
			end
			
			if Controller:IsA("Humanoid") then
				Controller.PlatformStand = true
			end
			
		end
	end
		
	for each, descendant in pairs (fake_char:GetDescendants()) do
		if descendant:IsA('Script') or descendant:IsA('LocalScript') or descendant.Name =="NPCInteract" then
			descendant:destroy()
		elseif descendant:IsA('BasePart') then
			descendant.Anchored = not PlatformstandToggle
		elseif descendant:IsA('Humanoid') then
			descendant.DisplayDistanceType = Enum.HumanoidDisplayDistanceType.None
		--[[elseif descendant:IsA("Motor6D") and PlatformstandToggle then
			--descendant.Transform = CFrame.new()
			descendant.DesiredAngle = 0
		end]]
		end
	end
	fake_char.Name = "Model"
	fake_char.Parent = workspace
	fake_char:SetPrimaryPartCFrame(CFrame.new(0, 10000, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1))
	RunService.Heartbeat:Wait()
	fake_char.Parent = viewport
	NPC.Archivable = true
	
	
	local viewportCamera = Instance.new("Camera")
	local npc_model = viewport:WaitForChild("Model")
	viewportCamera.Parent = viewport
	viewportCamera.CameraSubject = npc_model
	viewportCamera.FieldOfView = 20
	viewport.CurrentCamera = viewportCamera
	
	local focusPosition = npc_model:WaitForChild("Head").Position
	local Distance = 8
	
	viewportCamera.CoordinateFrame = CFrame.new(focusPosition + npc_model.Head.CFrame.LookVector * Distance, npc_model.Head.Position)
	return fake_char
end
6 Likes

Although somewhat poorly documented, I’d argue this is expected behavior. ViewportFrames don’t support physics, which means the Joints/Motor6Ds in the cloned character won’t update at all.

If you don’t want to temporarily parent the cloned character to workspace, you need to add a WorldModel to the ViewportFrame and parent the cloned character to the WorldModel. Then joints will update properly and you’ll be able to play or stop animations.

For more information see: WorldModel Is Now Available and https://developer.roblox.com/en-us/api-reference/class/WorldModel

30 Likes