ROBLOX Physics-based VR

Before anything, I apologize if this is in the wrong section.

The Issue
I have been trying to make a good physics-based vr system for the head and hands, but it’s been really difficult and i’d like some help and feedback. I have made 2 versions:

  1. The normal vr controller by just putting the usercframe as the head and hands cframe - Obviously the hands would clip through walls and the floor
  2. A successful but buggy prototype using AlignPosition and AlignOrientation (which I am currently using) but it’s just really laggy/buggy.

What I want to achieve
All I need is some support on this issue as documentation and examples of VR on roblox are quite limited. If anyone can provide me with some suggestions, alternative methods of making physics-based controllers or even just how I could improve my code would be greatly appreciated.

The Current Code
Local:

-- [[ Services ]] --
local vrservice = game:GetService('VRService')
local userinputservice = game:GetService('UserInputService')
local startergui = game:GetService('StarterGui')

-- [[ Variables ]] --
local events = game:GetService('ReplicatedStorage').Events
local player = game:GetService('Players').LocalPlayer
local character = script.Parent
local camera = workspace.CurrentCamera
local moving = false

-- [[ Functions ]] --
function updateVRCFrame()
	local vr_character = character:WaitForChild('PlayerVRModel')
	if not (vr_character.Head or vr_character.LeftHand or vr_character.RightHand) then return end
	
	local head_cframe = vrservice:GetUserCFrame(Enum.UserCFrame.Head)
	local left_cframe = vrservice:GetUserCFrame(Enum.UserCFrame.LeftHand)
	local right_cframe = vrservice:GetUserCFrame(Enum.UserCFrame.RightHand)
	
	events.UpdateVRCFrame:FireServer(head_cframe,left_cframe,right_cframe,camera.CFrame)
end

-- [[ VR ]] --
if vrservice.VREnabled then
	-- // Setup \\ --
	
	-- Camera --
	camera.HeadScale = 1
	camera.HeadLocked = true
	camera.CameraType = Enum.CameraType.Scriptable
	--camera.CFrame = CFrame.new(camera.CFrame.Position)
	
	-- Functions --
	events.CreateVRPlayer:FireServer() -- Creates the VR Character for the server
	vrservice.UserCFrameChanged:Connect(updateVRCFrame)

	character:FindFirstChild('HumanoidRootPart').Anchored = true
	vrservice:RecenterUserHeadCFrame()
end

Server:

local vr_player = game:GetService('ReplicatedStorage').PlayerVRModel
local weapons = game:GetService('ReplicatedStorage').Weapons
local events = game:GetService('ReplicatedStorage').Events
local vr_character

events.CreateVRPlayer.OnServerEvent:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		vr_player:Clone().Parent = character
		vr_character = character.PlayerVRModel
	end)
	if not player.Character:FindFirstChild('PlayerVRModel') then 
		vr_player:Clone().Parent = player.Character
		vr_character = player.Character.PlayerVRModel
	end
end)

events.UpdateVRCFrame.OnServerEvent:Connect(function(plr,head_cframe,left_cframe,right_cframe,camera_cframe)
	vr_character.Head.AlignPosition.Position = (camera_cframe*CFrame.new(head_cframe.p*1))*CFrame.fromEulerAnglesXYZ(head_cframe:ToEulerAnglesXYZ()).Position
	vr_character.Head.AlignOrientation.CFrame = (camera_cframe*CFrame.new(head_cframe.p*1))*CFrame.fromEulerAnglesXYZ(head_cframe:ToEulerAnglesXYZ())
	
	vr_character.LeftHand.AlignPosition.Position = (camera_cframe*CFrame.new(right_cframe.p*1))*CFrame.fromEulerAnglesXYZ(right_cframe:ToEulerAnglesXYZ()).Position
	vr_character.LeftHand.AlignOrientation.CFrame = (camera_cframe*CFrame.new(right_cframe.p*1))*CFrame.fromEulerAnglesXYZ(right_cframe:ToEulerAnglesXYZ())
	
	vr_character.RightHand.AlignPosition.Position = (camera_cframe*CFrame.new(left_cframe.p*1))*CFrame.fromEulerAnglesXYZ(left_cframe:ToEulerAnglesXYZ()).Position
	vr_character.RightHand.AlignOrientation.CFrame = (camera_cframe*CFrame.new(left_cframe.p*1))*CFrame.fromEulerAnglesXYZ(left_cframe:ToEulerAnglesXYZ())
end)
1 Like

Update the players VR positions on the server and client so the arms aren’t delayed

1 Like

Usually when I make a VR game I just give the client Network Ownership of the Hands root, Head, and Torso so it can all be done clientsided. This is also how Opposer VR works.

1 Like