Need help with VR camera & hand physics

Hello, I am trying to make one of my games I am working on VR compatible, however, I’ve come into an issue with camera and hand physics.
Whenever I move my head in real life, it disconnects from my player avatar & looks strange, and my hands aren’t where they’re supposed to be.
Shown in video:

I have tried looking on the devforum for answers but due to VR not being very well supported and not alot of developers are interested in it I did not find any solutions.

local VRService = game:GetService("VRService")
local Player = game.Players.LocalPlayer
local Character = Player.Character
local RunService = game:GetService("RunService")
local Camera = workspace.CurrentCamera
local UserInputService = game:GetService("UserInputService")
local RotateDebounce = false
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Events = ReplicatedStorage:WaitForChild("Events")
local RotateVR = Events:WaitForChild("RotateVR")
if VRService.VREnabled == true then
	local Humanoid = Character:WaitForChild("Humanoid")
	Humanoid.AutoRotate = false
	Camera.CameraType = Enum.CameraType.Scriptable
	Player.CameraMode = Enum.CameraMode.LockFirstPerson
        --Makes fake arms
	local FakeLeftArm = Character:WaitForChild("Left Arm"):Clone()
	FakeLeftArm.Name = "FakeLeftArm"
	FakeLeftArm.Parent = Character
	local FakeRightArm = Character:WaitForChild("Left Arm"):Clone()
	FakeRightArm.Name = "FakeRightArm"
	FakeRightArm.Parent = Character
	RunService.RenderStepped:Connect(function()
               --Get arm positions
		local RightHandCFrame = VRService:GetUserCFrame(Enum.UserCFrame.RightHand)
		local LeftHandCFrame = VRService:GetUserCFrame(Enum.UserCFrame.LeftHand)
                -- Set arm positions
		FakeLeftArm.CFrame = Camera.CFrame*CFrame.new(LeftHandCFrame.p*1) * (LeftHandCFrame - LeftHandCFrame.p) 
		FakeRightArm.CFrame = Camera.CFrame*CFrame.new(RightHandCFrame.p*1) * (RightHandCFrame - RightHandCFrame.p) 
		FakeLeftArm.LocalTransparencyModifier = 0
		FakeRightArm.LocalTransparencyModifier = 0
		Character:WaitForChild("Torso").LocalTransparencyModifier = 0
		Character:WaitForChild("Left Leg").LocalTransparencyModifier = 0
		Character:WaitForChild("Right Leg").LocalTransparencyModifier = 0
		local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart") 
		Camera.CFrame = HumanoidRootPart.CFrame+Vector3.new(0,2,0) -- Sets camera position
	end)
	UserInputService.InputChanged:Connect(function(input, processed) -- Character Rotation
		if input.UserInputType == Enum.UserInputType.Gamepad1 then
			if input.KeyCode == Enum.KeyCode.Thumbstick2 then
				if RotateDebounce == false then -- Checks if there isn't a debounce to avoid spinning alot
					if input.Position.X > 0.2 then
						RotateVR:FireServer("Right")
						RotateDebounce = true
						wait(0.3)
						RotateDebounce = false
					elseif input.Position.X < -0.2 then
						RotateVR:FireServer("Left")
						RotateDebounce = true
						wait(0.3)
						RotateDebounce = false
					end
				end
			end
		end
	end)
end
3 Likes
local cam = workspace.CurrentCamera
cam.CameraType = "Scriptable"

local leftcf = userinput:GetUserCFrame(Enum.UserCFrame.LeftHand) 
local rightcf = userinput:GetUserCFrame(Enum.UserCFrame.RightHand)

local headcf = userinput:GetUserCFrame(Enum.UserCFrame.Head)
local lcf = cam.CFrame * CFrame.new(leftcf.p*headscale) * (leftcf - leftcf.p) 

local rcf = cam.CFrame * CFrame.new(rightcf.p*headscale) * (rightcf - rightcf.p) 
local hcf = cam.CFrame * CFrame.new(headcf.p*headscale) * (headcf - headcf.p)

try using this to see if it fixes the out of place hands, also if you want physics use BodyPositions and BodyGyros

local cam = workspace.CurrentCamera
local offset = script.Parent.Torso.Position
local baseOffset = Vector3.new(0,5,0)
local userInput = game:GetService("UserInputService")
local headScale = cam.HeadScale


game:GetService("RunService").RenderStepped:Connect(function()
local headcf = userInput:GetUserCFrame(Enum.UserCFrame.Head)
local hcf = cam.CFrame * CFrame.new(headcf.p*headScale) * (headcf - headcf.p)

local activeOffset = baseOffset.Value + offset.Value
script.Parent.CFrame = hcf + activeOffset
cam.CFrame = CFrame.new(activeOffset)
end)

This should be able to help you with your camera problem.
Also please use this to disable the laser pointer

game.StarterGui:SetCore("VRLaserPointerMode", 0)
game.StarterGui:SetCore("VREnableControllerModels", false)