Motor6d Modify CFrame Animation (C0)

  1. What do you want to achieve?

Point the Weapon at a target with the rotation point being the center.

Below is the image of what I’m trying to achieve, the yellow circle being the RootPoint (RotationPoint Aswell) Red circle being the CFrame of it currently. I need to offset the original Frames C0 to get the position.

  1. What is the issue?

I cannot get the weapon to rotate and move by the rotation point.

function PointTowards(RotationPoint, TargetPosition, Gun, FrameCFrameC0)

I have the variables like so:

  • Position of RootPoint/RotationPoint.
  • The Position to look at.
  • The Gun/Arm Part itself.
  • The Frame’s C0 that is set.

How can I achieve this?

2 Likes

Hey there,

I understand what you’re trying to achieve, and if you’re familiar with trigonometry, specifically cosine & sine, you can do so by using the law of cosine deriving from inverse kinematics. Here’s an article explaining in depth of what you’re trying to achieve.

2 Likes

I don’t think you are fully understanding my problem.

I have frames of an animation that I need to rotate relative to a point. Here’s an example of a frame:

[workspace.Default.Torso["Right Shoulder"]] = {
		[1] = {
			["Position"] = CFrame.new(0.165085912, -0.0724334791, -1.49011612e-07, -0.173648477, -0.981060266, -0.085831672, 0.98480767, -0.172987685, -0.0151344594, 7.4505806e-09, -0.0871556997, 0.99619472),
			["EasingStyle"] = Enum.EasingStyle.Cubic,
			["EasingDirection"] = Enum.EasingDirection.InOut,
			["TimeToReach"] = 0
		},
		[2] = {
			["Position"] = CFrame.new(0.165095836, -0.0724296495, 2.68220901e-07, -0.0514078997, -0.994182825, -0.094612956, 0.991161227, -0.0391954593, -0.126685202, 0.122241072, -0.100284696, 0.987418592),
			["EasingStyle"] = Enum.EasingStyle.Cubic,
			["EasingDirection"] = Enum.EasingDirection.InOut,
			["TimeToReach"] = 1.75
		},
		[3] = {
			["Position"] = CFrame.new(0.165085912, -0.0724334791, -1.49011612e-07, -0.173648477, -0.981060266, -0.085831672, 0.98480767, -0.172987685, -0.0151344594, 7.4505806e-09, -0.0871556997, 0.99619472),
			["EasingStyle"] = Enum.EasingStyle.Cubic,
			["EasingDirection"] = Enum.EasingDirection.InOut,
			["TimeToReach"] = 1.83
		},
	},

I need to modify the Position of that (which is c0). Heres the code which sets the C0 (Frame is the frame number. DefaultC is the default C0 before the animation start.s):

local TweenInfoF = TweenInfo.new(Frame.TimeToReach, Frame.EasingStyle, Frame.EasingDirection)
local Tween = TweenService:Create(i, TweenInfoF, {C0 = DefaultC * Frame.Position})
Tween:Play()
task.wait(Frame.TimeToReach)
1 Like

Hey there again,

Can you explain your problem in greater detail so I can sort of scope what it exactly is you’re trying to achieve? I have a plethora of solutions, but I’m not entirely sure which to offer since I can’t fully understand what it is you want. Are you trying to convert and rotate a part based on its axis? If so, you could incorporate CFrame:PointToObjectSpace()? Or maybe I’m not fully understanding what it is you want and you’re looking for something more along the lines of CFrame:VectorToObjectSpace()?

Based on my understanding of your problem, you’re trying to make a part rotate in contrast to another points axes, either one of these functions should output the desired outcome of what you’re looking for, it more or less depends on how you go about using them. however if I am still missing things, please do not hesitate to explain more! :grinning:

2 Likes

Hey @JavaCompiled again.

I have already done this within my turret controller module.

The secret is to use CFrame.lookAt with the first parameter being an attachment where the gun muzzle is.

so

local GunMuzzle : Attachment --Is an attachment
CFrame.lookAt(GunMuzzle.WorldPosition, target.Position)

You will get the accuracy needed even if the Motor6D “Pivot” position is different or rigged differently.

The result:

2 Likes

Ah, looks like I might’ve overthought then X.x

Happens to the best of us!

Thanks for clearing this up! I guess that the answer was in front of me all along :sweat_smile:, I just more or less was having a little bit of trouble gauging what they were asking for. Nice work!

2 Likes

Thanks for trying to help out, I also used the IK article you linked which is very helpful in a general sense for CFrames and character related stuff.

I also believe it would be useful here in order to let the right arm hold on and stabilize the left arm which is carrying the gun. Perhaps for a more natural approach with the arm still attached to the shoulder.

However another option is to just weld the right arm to the left arm lol to make the arms move relative to each other like a static view model.

1 Like

Of course, I’m pretty burnt out after today… so if it’s anyone’s fault it’s mine. I should get rest before trying to answer questions! And of course, I’m only here to help. Mathematics have very cool concepts that I’d also like to help multiple people understand, as well as myself. But yeah, I totally overlooked the solution, thanks for stepping in :happy1:.

2 Likes


Currently, the Weapon is at the default C0 which is provided in the animation. I want it to aim at the transparent part.

As shown in my previous post, it is multiplying the C0 before being modified by the Frame’s C0.

I need something similar to the video (thanks Tower Defense Simulator!), which comes from the neck towards the part and solves the orientation based on that. If you feel the video is different from what I’m trying to solve please tell me.

In the image below, I show what may need to happen, which changes the angle on the different axis based on the point where the two lines I’ve drawn have originated from. The targeting is not based off of a look vector but rather the point where the lines originate from. Then the arms need to move according to that solved calculation.

1 Like

Instead of trying to find the direct solution to your problem, I came up with my own makeshift variation to this problem, a sort of way in which I’d go about solving this.

Take a look at this template place I made here, you can adjust to your liking and maybe learn something from it? Apologies though if not.

Motor6D Transformation.rbxl (35.0 KB)

I’ll get back to you tomorrow, it’s a bit late where I live right now. Best of luck, hope this helps! :wink:

2 Likes

This may be exactly what I’m looking for, I’ll respond back later when I have the time to implement it. I’ll also mark as solution if it works!

This is exactly what I want, the only issue is that:
image

When using R6, this is caused.

Here’s the code:

local RunService = game:GetService("RunService");

local Player = game:GetService("Players").LocalPlayer;
local Character = Player.Character or Player.CharacterAdded:Wait();
local Humanoid = Character:WaitForChild("Humanoid");

local ShoulderOffset = Character.Torso.CFrame:Inverse() * Character["Right Arm"].CFrame
local RightShoulder = Character.Torso["Right Shoulder"];


RunService.Heartbeat:Connect(function()
	local Radian = CFrame.Angles(math.pi/2, 0, 0); 
	local Constructed_CFrame = CFrame.new(Character.Torso.Position, workspace.Target.Position) * Radian;
	RightShoulder.C0 = ShoulderOffset * Character.Torso.CFrame:toObjectSpace(Constructed_CFrame);
end)

You can adjust the offset of said C0, you could probably just multiply the ShoulderOffset by a general direction, and it’d probably look like this:

ShoulderOffset = Character.Torso.CFrame:Inverse() * Character["Right Arm"].CFrame * CFrame.new(0,2,0);

Though this might not be fully accurate, I’m sure you can tell what I’m trying to do. You can try experimenting yourself by multiplying offsets w/ trial and error! :happy2:

Alrighty, so I now have the rig working well with just the regular old arms, but I don’t know how the apply the animation to it (I’ve tried and it miserably failed).

To be clear I’m going to restate one thing.

  • The Frame Position of the animation is the default C0 multiplied by the Frame (C0 = DefaultC * Frame.Position = Final animation.)
function PointTowards(RotationPoint, Part, Size, Motor, TargetPosition, Frame, DefaultC0, INVERT)
	local RightShoulder = Motor;
	local ShoulderOffset = RotationPoint.CFrame:Inverse() * Part * CFrame.new(0,Size.Y/2,0)
	
	
	local Radian = CFrame.Angles(math.pi/2,0,0)
	local Constructed_CFrame = CFrame.new(RotationPoint.Position, TargetPosition) * Radian;
	local SolvedRotation = ShoulderOffset * RotationPoint.CFrame:toObjectSpace(Constructed_CFrame)
	
	
	return SolvedRotation
end 

RotationPoint is the part which is being rotated around, Part is the part it’s calculating for at it’s default position. Size is the size of the part. Motor is as you would expect. TargetPosition is self explanatory, Frame is the Frame’s Position and DefaultC0 is the default C0 for the arm.

Here’s my place file to fool around in:
(removed)

How can I apply rotation to arms to produce what I want? (to the anim)

Thanks so much for the support! With a little editing here and there of @Pyritium 's code, (by a little I mean a whole lot) I was able to get this finished. All I need to do now is recode it to be a module!

Thanks all for your help!

Hey there,

Glad I could be of help. Sorry for not getting to you with your last question, I was asleep! (Darn time zones! :cry:)

I’m also glad you figured it out. Good luck in the future with your endeavors. :happy1:

1 Like

How did you do it? I am not experienced in cframe math and I really need help in achieving the same thing.

To my knowledge, I used an additional attachment inside the model to act as the “aim from here” point, placed where a weapon would be.

image

(SCROLL TO SEE COMMENTS)


-- Lovely function that I found on the devforum. Simply converts world cframe rotation to be used in a motor6D. https://devforum.roblox.com/t/basics-of-cframe-multiplication-and-weldsmotor6dsjoint-instances/1682079
function worldCFrameRotationToC0ObjectSpace(motor6DJoint, worldCFrame)
	local part0 = motor6DJoint.Part0
	local c1Store = motor6DJoint.C1
	local c0Store = motor6DJoint.C0
	local relativeToPart0 = part0.CFrame:inverse() * worldCFrame * c1Store

	local goalC0CFrame = relativeToPart0.Rotation + c0Store.Position --New orientation but keep old C0 joint position

	return goalC0CFrame
end

-- be warned, this is old code.
local attachmentLoc = TowerModel.Torso.Aim.WorldPosition -- The position of the attachment in charge of where you aim from, can be the model's torso too!
local distance = (attachmentLoc - enemyPosition).Magnitude -- The distance from the attachment to the enemy.
local p = (TowerModel.Torso.Aim.WorldCFrame * CFrame.new(0, 0, -distance)) -- This is the actual aiming location
local heightCorrection = Vector3.new(0, EnemyLocation.Position.Y - p.Position.Y, 0) -- This was used in my code to correct for the height offset of the enemy (I think)
p += heightCorrection

[Right Arm Motor].C0 = worldCFrameRotationToC0ObjectSpace([Right Arm Motor], CFrame.lookAt(attachmentLoc , p.Position)) -- This is where I update the motor.

The reason I did it this way instead of directly modifying the motor in relation to the torso was to make the animation not look wonky when shooting at an enemy that was a little offset of the torso. I built this code with the fact that the torso does not always align with the enemy, it simply snaps to the height of the enemy.

Feel free to ask any follow up questions! I probably should have left this here at some point. :slight_smile:

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.