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.
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.
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.
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.
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 ).
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).