Hello, I've been developing a basic arm and leg animation for a non-playable character, using CFraming methods. I'm not sure what is the problem, as the character moves as expected in the test environment, but "glitches" online; the character's torso and head move normally, but all the appendages become unattached to the torso, and appears to be doing the walking motion independently from the other body parts.
Firstly, I tried troubleshooting the problem; I know it can't be due to lag because I made sure the motion of the character would be activated on an on-clicked GUI event. The following is code that contains the script to move the non-playable person as a whole, excluding the animations:
local screenGui= game.Players.LocalPlayer.PlayerGui.screenGUI local blackscreen= Instance.new("Frame",screenGui) blackscreen.Name= "BlackScreen" blackscreen.Position= UDim2.new(0,0,0,0) blackscreen.Size= UDim2.new(1,0,1,0) blackscreen.BackgroundColor3= Color3.new(0,0,0) blackscreen.ZIndex= 10 local beginButton= Instance.new("TextButton",screenGui) beginButton.Name= "BeginButton" beginButton.Position= UDim2.new(0.25,0,0.77,0) beginButton.Size= UDim2.new(0.20,0,0.06,0) beginButton.Text= "Begin" beginButton.FontSize= "Size24" beginButton.TextColor3= BrickColor.Black().Color beginButton.BackgroundColor3= BrickColor.White().Color beginButton.ZIndex= 10 beginButton.MouseButton1Up:connect(function() blackscreen:Destroy() beginButton:Destroy() --game.Players.LocalPlayer.PlayerGui.MenuGui.Disabled= false --actual camera for use local camera= workspace.CurrentCamera local target= workspace.CameraForProductionIntro.Part camera.CameraType= 6 camera.CameraSubject= target camera.CoordinateFrame = CFrame.new(target.Position) --part position --[[ --testing local camera= workspace.CurrentCamera local target= workspace.CameraForProductionIntro.Part camera.CameraType= 3 camera.CameraSubject= target --]] for i=1,200 do --moves the entire model wait(0) workspace.NPC:TranslateBy(Vector3.new(0.2,0,0)) end local box= workspace.Box:Clone() box.Parent= game.Workspace local boxX= -4.5 box.Position= Vector3.new(boxX,2002.5,5.5) local productionsText= Instance.new("TextLabel",screenGui) productionsText.Size= UDim2.new(0.75,0,0.1,0) productionsText.Position= UDim2.new(0.1,0,0.2,0) productionsText.FontSize= "Size24" productionsText.BackgroundTransparency= 1 --productionsText.TextStrokeTransparency= 0 productionsText.TextStrokeColor3= BrickColor.White().Color productionsText.TextColor3= BrickColor.Black().Color productionsText.Text= "Box on Fire Productions Presents" for i=1,300 do wait(0) boxX= boxX+0.2 box.Position= Vector3.new(boxX,2002.5,5.5) end workspace.Box:Destroy() productionsText:Destroy() -- code below moves the model back to original position repeat--fast enough noone can see it coming, therefore placed before camera changes workspace.NPC:TranslateBy(Vector3.new(-10,0,0)) until workspace.NPC.PrimaryPart.Position.X< 0 --print(workspace.NPC.PrimaryPart.Position) camera.CameraSubject= game.Players.LocalPlayer.Character.Humanoid camera.CameraType= 5 workspace.AnimationSwitch.Value= 1 end)
Basically, the function I am using is TranslateBy
, shown above. Below is a sample script for the animation of the left arm (a walking type of motion which runs continuously), which is placed under the left arm Part:
while true do local pos1= workspace.NPC.LeftArm.Position.Y --print("Pos 1: "..workspace.NPC.LeftArm.Position.Y) for i=1,7 do workspace.NPC.LeftArm.CFrame= workspace.NPC.LeftArm.CFrame*CFrame.Angles(0,0,0.1)*CFrame.new(0.05,0,0) wait(0) end wait(0.2) for i=1,7 do workspace.NPC.LeftArm.CFrame= workspace.NPC.LeftArm.CFrame*CFrame.Angles(0,0,-0.1)*CFrame.new(-0.05,0,0) wait(0) end for i=1,7 do workspace.NPC.LeftArm.CFrame= workspace.NPC.LeftArm.CFrame*CFrame.Angles(0,0,-0.1)*CFrame.new(-0.05,0,0) wait(0) end wait(0.2) for i=1,7 do workspace.NPC.LeftArm.CFrame= workspace.NPC.LeftArm.CFrame*CFrame.Angles(0,0,0.1)*CFrame.new(0.05,0,0) wait(0) end --workspace.NPC.LeftArm.CFrame= workspace.NPC.LeftArm.CFrame*CFrame.new(0,-0.05,0) local pos2= workspace.NPC.LeftArm.Position.Y local pos3= pos2-pos1--positive --print("Pos 2: "..workspace.NPC.LeftArm.Position.Y) workspace.NPC.LeftArm.CFrame= workspace.NPC.LeftArm.CFrame*CFrame.new(0,-pos3,0)--if too high should go down, so '-' sign end
The other three appendages would follow suit.
My attempt to resolve the situation was to take notice that the primary part was the head, in the case that it was the only part that actually contained a weld. Therefore, my idea was to add a weld to the other parts, something like this:
local leftArmToTorso= Instance.new("Weld",game.JointsService) leftArmToTorso.Part0= workspace.NPC.Torso leftArmToTorso.Part1= workspace.NPC.LeftArm leftArmToTorso.C0= CFrame.new(0,0,0) leftArmToTorso.C1= CFrame.new(0,0,-1)
The use of CFrames in this case is to not only bind the two pieces but to provide an imaginary axis where those two parts would share when the translation happens. The left arm should be one z-value stud relative to the torso. To reiterate, I'm trying to effectively move/ translate animated CFramed moving parts from a certain point A to point B, making sure it stays relative to the torso and head. In addition, I've made sure to disable FilteringEnabled
for the time being. To also clarify, by default the model had no animation scripts on the four appendages, so when the whole model was moving, the arms and legs would remain in the downward position.