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

How do I set only the Orientation of a CFrame?

Asked by 6 years ago

As far as I understand, a CFrame can generally be broken down like this: CFrame.new(Vector3 pos, Vector3 lookAt) My last question was about using welding to allow for rotation, which I solved using constraints. I needed to allow rotation because I want a gun to point at the mouse (think Metroid Prime). Here's my code:

wait(2)
playerTable = game.Players:GetChildren()
player = playerTable[1]
print(player)
mouse = player:GetMouse()
att = Instance.new("Attachment")
att.Parent = player.Character["Right Arm"]
con = script.Parent.GunCon
con.Attachment1 = att
con.Attachment0 = script.Parent.Attachment
wait(10)
while true do
    wait()
    script.Parent.CFrame = CFrame.new()--, mouse.Hit.p)
end

If I set the position vector3 of the CFrame, it constantly messes with the position of the gun, as to be expected; however, I need to access the second argument of the CFrame without accessing the first. I want to leave the position be and use mouse.Hit.p as the orientation. I hope that makes sense. Thanks.

1
Just do `script.Parent.CFrame.x,script.Parent.CFrame.y,script.Parent.CFrame.z` and so on and replace one with what you want to change. Decemus 141 — 6y
0
It doesn't work like that because it would constantly set the position to the current position and when i do that is seizes up and everything goes crazy UnityAlex 36 — 6y
1
Then do it for all 12 properties Decemus 141 — 6y
0
What do you mean? UnityAlex 36 — 6y
0
i have that same exact question! botw_legend 502 — 3y

2 answers

Log in to vote
1
Answered by
kazeks123 195
6 years ago
Edited 6 years ago

I think you could use BodyGyro to rotate the Parent of the script. That way you would only need to rotate BodyGyro's CFrame and since BodyGyro doesn't apply any force to keep its position, but does only to rotate it's parent, there should be no worry of CFrames position. Tutorial on body movers (BodyGyro at the end of the vid): https://www.youtube.com/watch?v=wlYBQBnDEVI .

Edit: Even better! You could combine this with the post above doing: BodyGyro.CFrame * CFrame.Angles()

0
Thanks for the info! Unfortunately, something weird is happening. My goal is to set the rotation of the CFrame by using a lookat vector, so I set the position I want it to look at and it will face that position. When I use the BodyGyro, it doesn't face the direction I set it to. It rotates to a random direction with no visible pattern that I can find. Any idea what's going on? Thanks UnityAlex 36 — 6y
0
I got it working! Basically to sum up the problem I diagnosed and solved: when I set the CFrame of the BodyGyro, the lookAt vector3 is not looking at it from the gun's position but rather from the position set in the CFrame (the first Vector). thank you! UnityAlex 36 — 6y
Ad
Log in to vote
4
Answered by 6 years ago
Edited 6 years ago

Fundamentals


I don't think you understand the full potential of CFrame. Passing a position and direction vector to CFrame is only one of several different CFrame constructors. No matter what constructor you use, your CFrame value will always have the same parameters: PositionX, PositionY, PositionZ, Rotation00, Rotation01, Rotation02, Rotation10, Rotation11, Rotation12, Rotation20, Rotation21, Rotation22 (in that order).

The first three arguments make up the 3D position for the CFrame, and last nine arguments comprise the rotation matrix. Now you see why there are different CFrame constructors, keeping track of each element in the rotation matrix every time you wanted to rotate something could get a bit complicated.

Position and rotation are different


Position and rotation have no direct correlation with each other. You can change one without it effecting the other (just make sure the constructor allows for it). If you wanted to change the position without changing the rotation, here are a few examples...

Converting Rotation vector to radians

-- Converting all vector dimensions to radians for the CFrame.Angles constructor
local partRot = part.Rotation
local rad = math.rad

part.CFrame = CFrame.new(x, y, z) * CFrame.Angles(rad(partRot.X), rad(partRot.Y), rad(partRot.Z))

Using CFrame components to extract the rotation matrix

-- Gets the arguments after the 4th position, which is the rotation matrix.
part.CFrame = CFrame.new(x, y, z, select(4, part.CFrame:components()))

If you wanted to change rotation without modifying position, here is an example...

-- Creating a new CFrame with a position with an empty rotation matrix, then filling it by using CFrame.Angles
part.CFrame = CFrame.new(part.Position) * CFrame.Angles(x, y, z)

There are always several ways to do the same thing, some options are better than others depending on what you're doing. Anyways, hope this helped clear things up a bit. Let me know if you have any questions.

0
This is all good information and I appreciate it! However, I am specifically looking for a way to set the LookAt Vector3 in the constructor I showed in the post without modifying the position vector3. This tells me how to set the rotation of the CFrame but I specifically want it to look at a point (the mouse). UnityAlex 36 — 6y

Answer this question