self = script.Parent
local waist = self.UpperTorso.Waist
local w0 = waist.Transform
local neck = self.Head.Neck
local n0 = neck.Transform
game:GetService("RunService").Heartbeat:Connect(function()
local x1,y1,z1 = self.HumanoidRootPart.CFrame:ToOrientation()
local x2,y2,z2 = self.LowerTorso.CFrame:ToOrientation()
local direction = self.HumanoidRootPart.CFrame:PointToObjectSpace(workspace.target.Position).Unit
local verticalAngle = math.deg(math.asin(direction.Y))
local horizontalAngle = math.deg(math.atan2(-direction.X, -direction.Z))
neck.Transform = n0 * CFrame.Angles( 0,math.rad(horizontalAngle),0)
end)
in addition i have an animation that rotates the head 30 degrees left
When i dont play the animation it works fine otherwise The animation plays normally and transform does not move the head towards the target No matter if its set to core or action4, the animation will play like nothing happens and the head will not rotate towards the target
Expected behavior
Transform property should override any animations and not be affected by them
You need to set the .Transformafter Animations have been applied for the frame, which you should be able to do by connecting to .PreSimulation and not .Heartbeat (AKA PostSimulation).
This is not documented AFAIK, but Animators only reset the .Transforms of a rig every frame if there are animations playing. If there are no animations playing, then Transforms are not reset.
The overwriting behavior however, is documented on the page for the .Transform property:
The internal CFrame that is manipulated when a Motor6D is being animated. It is recommended to use this property for custom animations rather than JointInstance.C0 and JointInstance.C1.
Timing
Motor6D transforms are not applied immediately, unlike updating C0 and C1, but rather as a batch in a parallel job after RunService.PreSimulation, immediately before physics steps. The deferred batch update is much more efficient than many immediate updates.