Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
1

How to fix this problem pointing a rig's arms?

Asked by 6 years ago

Hey! So recently I've been trying to figure out how I can aim an R6 rig's arms to a location.

So here's what I did so far:

I made a new part to be the shoulder joint for the right arm, welded that part to the right arm, then offset it's CFrame so it's in the position of the shoulder.

Then, I created a part to be the fake right arm. I welded that arm to the shoulder joint I just made, and then I would adjust the fake arm's weld CFrame utilizing CFrame.Angles to point it at a location.

I tested this method, using the code shown below in a loop:

w2.C0 = w2.C0 * CFrame.Angles(math.rad(1),math.rad(1),0)

And everything I did worked! The fake arm rotated around the shoulder joint correctly.

However, everything started going downhill when I changed the code to this:

w2.C0 = CFrame.new(w2.C0,game.Workspace.Point_To_This_Brick.CFrame.p)

The arm didn't point on-key, it was horrific.. I can't figure out why this code isn't working correctly. But I did make an assumption, on how to get this code working, in which I'm unable to solve it...basically to do some kind of operation to find the angle between the arm/shoulder joint, to the location brick, and then use that information in CFrame.Angles.

I'm really not that good with mathematics.. any help on the subject would be highly appreciated. Thanks guys!

1 answer

Log in to vote
0
Answered by
EgoMoose 802 Moderation Voter
6 years ago

Adjusting the player's joints can be a bit tricky since they're setup in a certain way for tools and animations etc. Sometimes the trick really is just to start with the basics and then adjust from there. All that said, here's how I approached it...

I know the shoulder joints (motor6D) on R6 work like this:

torso * c0 -> where the arm and shoulder connect

torso * c0 * c1:inverse() -> arm world space

So we have two points. The c1:inverse() is for the most part transitional, not rotational so no need to adjust that and make our lives more complicated. The torso * c0 however brings to a position you might describe as having a ball and socket characteristic, perfect for rotation.

With that in mind we:

(1) Calculate that world space cframe

(2) Include the rotation from that point to the mouse

(3) Find the rotation relative to the original cframe such that cf * lrot == rot

(4) apply the object space rotation and add some additional rotation offsets (mostly trial and error)

local player = game.Players.LocalPlayer;
local mouse = player:GetMouse();
local rs = player.Character:WaitForChild("Torso"):WaitForChild("Right Shoulder");

local c0 = rs.C0;

game:GetService("RunService").RenderStepped:connect(function(dt)
    local cf = rs.Part0.CFrame * c0; -- (1)
    local rot = CFrame.new(cf.p, mouse.Hit.p); -- (2)
    local lrot = cf:toObjectSpace(rot); -- (3)
    rs.C0 = c0 * lrot * CFrame.Angles(0, math.pi/2, math.pi/2); -- (4)
end)
Ad

Answer this question