I am working on a script to make a character look at a target position. It works fine when I am changing the transform of a single part (just the head in this case):
but when I start changing the transforms of multiple parts at once, there is a slight offset from the target position when the parts need to rotate on more than one axis:
My first thought was that because I check attachment.WorldCFrame to find the local angle I need to transform the joint by, maybe I was reading a stale value and not the WorldCFrame after I transformed the motor. Also, maybe I’m updating the Neck before the Waist, so the Neck isn’t accounting for Waist’s offset. I changed the code a bit to force Neck to always update after Waist, and passed the world CFrame * the transform I made to the angle calculator to make sure I wasn’t using stale data, and neither helped me.
Any idea what else it could be? Here is a repro file stripped down to be bare bones and without the hacks I made previously (e.g. forcing Neck to be updated after Waist): LookThing.rbxl (24.1 KB)
ServerScriptService > PerspectiveLookPackage > PerspectiveLookClientService is where the meat of the file is. Relevant code:
local function getTargetAngle(motor, targetPosition) local childAttachment = motor.Parent:FindFirstChild(motor.Name.."RigAttachment") local rootAttachment = motor.Part0:FindFirstChild(motor.Name.."RigAttachment") local rootCFrame = rootAttachment.WorldCFrame local rootLookVector = rootCFrame.LookVector local rootYaw = math.atan2(rootLookVector.X, -rootLookVector.Z) local rootPitch = math.atan2(rootLookVector.Y, math.sqrt(rootLookVector.Z^2 + rootLookVector.X^2)) local lookVector = CFrame.new(childAttachment.WorldCFrame.Position, targetPosition).LookVector local pitch = math.atan2(lookVector.Y, math.sqrt(lookVector.Z^2 + lookVector.X^2)) local yaw = math.atan2(lookVector.X, -lookVector.Z) local viewAngleLocalSpace = transformLastAngleToCurrentSpace(Vector2.new(yaw, pitch), Vector2.new(rootYaw, rootPitch)) return viewAngleLocalSpace end ... RunService.Stepped:Connect(function(_, dt) for character, metadata in pairs(viewAngleMetadata) do for motorName,motorData in pairs(metadata.Rig) do local motor = character:FindFirstChild(motorName, true) local spring = motorData.Spring local targetViewAngle = getTargetAngle(motor, metadata.Target) spring:SetGoal(targetViewAngle * motorData.Weights) local viewAngle = spring:Update(dt) motor.Transform = motor.Transform * CFrame.Angles(0,-viewAngle.X,0) * CFrame.Angles(viewAngle.Y,0,0) end end end)