How to change CFrame Origin property through script

Hello, I have a couple light switch models that animate up/down when they are clicked. These models are all around the map and are being coded using tags and OOP. I am having trouble with coding the CFrames for the animation because they are all facing in different directions. Does anyone know how to do this? Thanks.

This is what I mean by Origin. The properties are different than CFrame

Maybe

I’ve tried this before and I am still so confused on how to do it. I have looked at so many tutorials on how to do it but I never understand it

1 Like

Im gonna be honest so that I don’t waste your time, I’m not sure how you’d do this either lol

1 Like

I have tried doing this:

Angles = Switch.CFrame - Switch.Position

TweenGoal = {
   CFrame = CFrame.new(Switch.Position):ToWorldSpace(CFrame.Angles(angles.X, angles.Y, math.rad(-127))
}

1 Like

Yeah I’ve got no clue what’s going on there lol

2 Likes
Object = workspace.MeshPart
CF = {Object.CFrame:GetComponents()}
print(CF)

1, 2, 3 = Position (X, Y, Z)
4, 5, 6, 7, 8, 9, 10, 11, 12 = Orientation (This is you need)

I don’t understand how I would use this info? Can you help me

Sure. It’s the kind of tool you won’t always use, but you know it’s there if you need it.

Same example:

Object = workspace.MeshPart
CF = {Object.CFrame:GetComponents()}

Object2 = workspace.MeshPart2
CF2 = {Object2.CFrame:GetComponents()} -- Just to shorten the line below.
Object2.CFrame = CFrame.new(CF2[1], CF2[2], CF2[3], CF[4], CF[5], CF[6], CF[7], CF[8], CF[9], CF[10], CF[11], CF[12])

By doing this you keep the position of Object2 the same, but with the orientation of the primary Object.

You can’t edit the Origin property directly, you can either used the Edit Pivot tool in Studio’s Model, tab, or set Part.PivotOffset to the desired offset CFrame. The Origin in just showing you Part.CFrame x Part.PivotOffset, so that you can see where exactly it ended up. Origin used to be called Pivot, but this was apparently confusing, but its purpose is still the same, it’s a reference point on the part where you want the origin of transforms to be (the pivot point of rotations, mainly) both for Studio’s transform tools, and for using PivotTo(), etc. from code.

When you have multiple models that you want to use with the same animations, normally what you need to do is make sure that the animated motors are all aligned the same way relative to the parts. If your models are already rigged with Motor6Ds, you can re-orient the axes of the motors by making the same rotation changes to both Motor6D.C0 and C1. If your animations are not literally Animator-based, but using code and/or constraints (e.g. HingeConstraint) then it’s a matter of getting the Attachment orientations the same in all models.

1 Like

@EmilyBendsSpace @Candy_Project
I think I realized what I am trying to do. I am trying to rotate the switch based on the PivotOffset. I looked up for ways to do this but they don’t really work. Can anyone help?

I think the ideal would be for you to show in a video more or less what is happening and how it should happen.

1 Like

Basically this but with a light switch

How to rotate a part around its pivot??

You can’t animate the Origin property directly: it needs to be modified indirectly through functions like PivotTo.

How I do this for simple rotation animations is:

  • For the parts that move during the animation:
  • Weld all of the parts to a “central part”
  • Unanchor all the parts besides the central part
  • Tween the CFrame of the central part
  • By positioning the central part you can position the rotation point

(Edit: I haven’t used Motor6s outside of characters. Looks like they can do lots of cool stuff and get smoothing when replicated! I would definitely recommend EmilyBendsSpace’s approach.)

Make sure the central part is at the center of the rotation (e.g. for a door, the hinge point, and–similarly–for a light switch, at the hinge point for the switch). I usually make the central part non-collide and invisible so it can be positioned at the right spot.

Then you need to tween it’s CFrame. You want to rotate it relatively like you mentioned so all the models work even if they’re facing different directions.

You can rotate a CFrame relatively with:

local cframe = -- [your cframe]
-- Ex: 90 degrees around the X axis
local rotation = CFrame.Angles(math.rad(90),0,0)
-- Do a relative rotation
local rotated = cframe * rotation

IMO this is the most intuitive way to do this. A motor6 (and tweening C0/C1) or a RigidContraint (and tweening an attachment’s CFrame) are also good choices though.

(Edit: See reply below. TL;DR: you’ll get smoother animations for server-sided movement using Motor6Ds (or HingeConstraints). Otherwise to get the same smoothness you’d need to run the tween on all the clients.)

1 Like

For a simple 1-axis toggle or rotary switch animation with a Motor6D, you can simply use the DesiredAngle property and MaxVelocity property to have the switch rotate between two (or more) positions specified as angles. For something more complex, you’d want to animate the Motor6D using the Transform property; it’s not advisable to animate C0 or C1 from Lua (at one point, Roblox used to even throw a warning to the Output window if you did this, because there can be performance implications).

With a HingeConstraint, likewise you shouldn’t manually tween or script the attachment CFrames, instead you’d use the hinge in Servo mode and set the angles, just like you’d do for a Motor6D.

Both of these approaches allow for the system to only replicate the target angle from the server to all clients, and all of the visual “tweening” is handled automatically in engine, with no TweenService or Lua RunService code needed to ensure smooth, framerate-independent animation everywhere. TweenService was added primarily for animating GUIs, like for sliding windows on and off screen, fading things out, etc. There are usually easier and better ways for animating Parts and things in the 3D workspace.

2 Likes

Could you show the model? I think I have an idea.