How to convert direction to angle?

does anyone know how to convert a 3d direction to an angle that my part would rotate to?

i am not referring to UI or other related graphical user interface

basically what i want to do is make my part have the same orientation as the other part by getting the other part’s direction then convert it to an angle so the parts would have the same orientation

ask some questions if your confused

1 Like

you can do this by using the parts cframe orientation or also by using the cframe lookvector if the part is facing the direction you want the other one to
then use something like CFrame.lookAt(Position, lookVector of first part)
this can also be done with just CFrame.new(Position, lookVector)

https://create.roblox.com/docs/reference/engine/datatypes/CFrame#lookAt

other than that how would i do it using math? like direction to angle using math because i need it for like camera related things and others

math.acos(v0.Unit:Dot(v1.Unit))

v1 - the vector
V0 - the vector relative to which you want to find the angle

The dot product returns the cosine between the vectors, and math.acos() converts the cosine to radians. It’s simple

Why would you look for an angle if you can just do this?:

part0.CFrame = part1.CFrame.Rotation + part0.Position
1 Like

This^

This sounds like an XY Problem.

What kind of camera manipulation are you trying to do exactly? There is no such thing as a conversion from a singular vector to an angle — you have to define a second vector which that angle sits between.

You probably have something similar in mind to Euler angles, but if you’re simply trying to copy the orientation of one part to another part then you already have the solution here. A specific example of the feature you’re trying to achieve will be better than trying to guess what kind of math you might need.

1 Like

i am simply trying to make a thing that rotates the player’s character’s head to camera direction infront

You should show code for this system and ask about a specific issue related to that, instead of asking a broad question with little context. I agree with @pullman45

Okay so let’s just start with a simple script that only moves the head without anything fancy. This simple script doesn’t even involve any angle calculations.

If you want to make the character’s head turn gradually or prevent it from turning to face backwards like an owl, then you need more code.

You have to manipulate the Motor6D representing the player character’s neck joint in order for the character to still function. You can do this by either updating the C0 or Transform property of the Motor6D. I won’t explain what C0 and Transform do because you won’t understand it without a picture and I’m on my phone at 4am so I can’t make a demo rn.

The Transform method (more optimized and less math)
local RunService = game:GetService("RunService")

local neck: Motor6D -- the “Neck” joint under the Head of an R15 char, or the “Neck” joint under the Torso of an R6 char

local cam = workspace.CurrentCamera
local upperTorso -- reference to the upper torso of an R15 char. If you’re using R6 then this is just the torso

local connection = RunService.PreSimulation:Connect(function()
    local neckCFrameWorld = upperTorso.CFrame * neck.C0
    neck.Transform = neckCFrameWorld:ToObjectSpace(cam.CFrame).Rotation
end)
The C0 method
local RunService = game:GetService("RunService")

local neck: Motor6D -- explained in example above 

-- you HAVE to declare this at the start. short for “initial C0”
-- notice how this is an extra step compared to using Transform
local init_C0 = neck.C0

local cam = workspace.CurrentCamera
local upperTorso -- explained in example above

-- Since this is using C0 we don’t need to use PreSimulation. You could even use a while loop if you wanted to.
local connection = RunService.Heartbeat:Connect(function()
    local neckCFrameWorld = upperTorso.CFrame * neck.C0
    neck.C0 = init_C0 * neckCFrame:ToObjectSpace(cam.CFrame).Rotation
end)

I wrote this whole post on my phone so the code is untested (this is supposed to be a general idea).

Choosing between Transform or C0

Motor6D.Transform — often less math but requires to be updated in a RunService.PreSimulation event. Also overrides any animations that are affecting the head (this doesn’t matter unless you want the head to turn with the camera AND be able to play an animation on the head). You could technically make it not do that but that requires a few extra lines of code.

Motor6D.C0 — does not require to be in PreSimulation, but does require you to save the initial C0 in a variable in order to maintain the structure of the joint. Less optimized than Transform. Lets you change the orientation of the joint while still allowing animations to be played without extra code.