Rotate a CFrame orientation like a vector

I’m making a gyroscopic camera system and I’m trying to make the head look where the user is looking. By default the head rotates with the torso so an offset has to be applied to counter this.

This offset disalign the other axises creating unwanted behaviour where if you bend down it will bend on the left and so on.

It is like rotating a part whitout updating the RightVector.

1 Like

Dude you just need to figure out the orientation of set up and multiply by a CFrame. This is what was suggested in the other thread.

2 Likes

Well, as I stated before, this doesn’t work as the desaligment is still present. Or I don’t understand what you are telling me.

1 Like

Share the code you are currently using which causes this axis alteration and I may be able to provide some help

1 Like

So you need to take the camera vector and multiply by the inverse of the character’s vector and get the angle of the resulting vector, then apply that to the neck joint.

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

local Players = game:GetService("Players")
local Player = Players.LocalPlayer

local Character = Player.CharacterAdded:Wait()

local Head = Character:WaitForChild("Head")
local Neck = Head.Neck
local NeckConnect = Neck.Part0

local Camera = workspace.CurrentCamera
local CurrentRotation = Camera.CFrame

wait()

if UserInputService.GyroscopeEnabled then
	Camera.CameraType = "Scriptable"

	RunService:BindToRenderStep("Camera", Enum.RenderPriority.Camera.Value, function()
		local Input, RotCFrame = UserInputService:GetDeviceRotation()
		local X, Y, Z = RotCFrame:ToOrientation()

		CurrentRotation = CFrame.fromEulerAnglesYXZ(X, Z, Y):ToWorldSpace(CFrame.Angles(math.rad(-90), 0, 0))
		Camera.CFrame = CFrame.new(Head.Position) * CurrentRotation
		Camera.Focus = CFrame.new(CurrentRotation * Vector3.new(0, 0, -10))
		Neck.C0 = CFrame.new(Neck.C0.Position) * (CurrentRotation * NeckConnect.CFrame.Rotation:Inverse())
	end)
	
	Player.CharacterAdded:Connect(function(NewCharacter)
		wait()
		Character = NewCharacter
		
		Head = Character:WaitForChild("Head")
		Neck = Head.Neck
		NeckConnect = Neck.Part0
	end)
end

It works perfectly but if the torso rotation isn’t 0 then it will start to desalign. And some of the modifications to the rotation are made due to IOS axises being swaped.

It has been an hour since the last sign of activity. Could you clarify if you are able to help with this or not.

Thanks!

So most of the action seems to be happening on this line here:

but the CurrentRotation CFrame is also of interest.

Presumably the camera is meant to be positioned relative to the torso / Neck.Part0.

I think the solution looks something like this.

Camera.CFrame = CFrame.new(Head.Position) * RotCFrame.Rotation
Camera.Focus = Camera.CFrame * Vector3.new(0,0,10)

 Neck.C0 = RotCFrame.Rotation * Neck.Part0.CFrame:inverse() * CFrame.new(Neck.Part1.Position)

Now if you have issues with axes not being what you expect you can replace RotCFrame.Rotation with something like CFrame.Angles(x, y, z) * RotCFrame.Rotation where you’ll need to figure out x, y, z.

you could try

CFrane1:ToWorldSpace(CFrame.Angles(X, Y, Z))

The piece of code you gave me didn’t fix the issue as there is nothing to realign the axises neither did it works ( tough it was funny see the head fly away ).

About the way to fix the axises, the x, y, z component are the rotation of the torso and multiplying the two doesn’t work. As I stated before, to realign the axises we need to “rotate”/swap but in a way which follows the torso rotation so just swapping one axis for another will not always work.

Thanks anyways, and if you have something else in mind, feel free to tell me.

Surprisingly, this doesn’t work. Tough, if you look at the code, I’m using this function to apply an offset to the rotation for the camera ( cameras have a -90 degrees offset ) and, make the axises align after I did to prevent the same issue from happening.

if you wanted to use degrees you would have to use math.rad() because this constructer takes in radians

I do use math.rad else it just breaks as it try to interpret degrees as radians.

so if you use math.rad it breaks?

No, if I don’t use it, it breaks.

I guess you didn’t try and tweak it then or try this:

I did try it multiple times but it only piles them on top of one another ( add ).
This is the pile up behaviour I’m talking about.

[ 1, 0, 0 ] +
[0, 1, 0 ] =
[ 1, 1, 0 ]

What I’m trying to do is rotate the “axises” themself as if they were directions vectors ( UpVec, RightVec … ) on a part which gets rotated so maybe the up vector will become ( 1, 0, 0 ) and so on. You can see the behaviour I want if you do :
CFrame.Angles(math.rad(45), 0, 0):VectorToWorldSpace(Vector3.new(0, 90, 0))

It is close to what I need but it returns weird values as in this case ( 0, 63, 63 ) instead of ( 0, 45, 45 ).

CFrame.Angles(math.rad(45), 0, 0):VectorToWorldSpace(Vector3.new(0, 90, 0)) is the same as CFrame.Angles(math.rad45), 0, 0) * Vector3.new(0,90,0).

Your explanation in terms of adding vectors makes no sense to me as that is not how rotations with cframes work.

To clarify further if you want to rotate between axis you can multiply by CFrame.fromAxisAngle( Vector3.new(1,1,1).Unit, math.rad(120) ) and that should send x → y, y → z z → x (or the other way round).

This is maybe what I need. Though if it is, It will still need a bit of modifications.