Cant Properly keep the VR players body under the head without issue

I have been working on a barebones R6 VR that uses the players character model (basically just want moving arms and head attached to a normal R6 body), but I came across an issue I still couldn’t find out after two months.

I am attempting to keep the VR players humanoid rootpart / Torso under the VR cameras head by using a calculated distance between the VR headsets current and last frame.

After applying that, I realized that moving the rootpart also moved the camera, causing the camera and rootpart to move at different speeds.

To fix this I tried to make the camera scriptable and change its subject to the head that way this wouldn’t happen, but of course as the scripter contract goes “fixing a bug can cause many more to arise.” Sure the rootpart now properly follows the head but now the body can roam free like a zombie.

Here is (yes my entire) code if you wanna use it for something go ahead VR needs more love.

local player = game.Players.LocalPlayer
local character = script.Parent 
local module = require(character.SNVRCONFIG)

-------------
local oldpos = Vector3.new()

local currentpos = Vector3.new()
-------------
local camera = workspace.CurrentCamera
local humanoid = character:WaitForChild('Humanoid')
local root = character:WaitForChild('HumanoidRootPart')
local torso = character:WaitForChild('Torso')
local leftarm = character:WaitForChild('Left Arm')
local rightarm = character:WaitForChild('Right Arm')
local head =  character:WaitForChild('Head')

local RNS = game:GetService("RunService")
local vrsrvice = game:GetService('VRService')
local vrstatus = game:GetService('VRStatusService')

if vrsrvice.VREnabled == true then
	
print(character, "IS in VR")	

local function PreparePlayerForVR()
	
	camera.CameraType = Enum.CameraType.Scriptable
	--camera.HeadLocked = false	
	print('Initializing VR')
camera.CFrame = root.CFrame * module.bodyoffset
	--vrsrvice.AutomaticScaling = Enum.VRScaling.World
	vrsrvice.FadeOutViewOnCollision = true
	--vrsrvice.ThirdPersonFollowCamEnabled = false
	
	leftarm.Massless = true
	rightarm.Massless = true
	head.CanCollide = false --for now have it like this until you can find out how to have the head and torso specifically not be able to collide with each other
	torso['Left Shoulder'].Enabled = false
	torso['Right Shoulder'].Enabled = false --disable the attatchments so they cannot be animated
	torso['Neck'].Enabled = false
	player.CameraMaxZoomDistance = 0
	player.CameraMinZoomDistance = 0

	camera.CameraSubject = head
	print('Camera Subject:', camera.CameraSubject)
	
	if module.VRvisibilitymode == 'FullBody' then
		
	for i, child in pairs(character:GetChildren()) do
		if child:IsA('BasePart') then
			wait(0.1)
			
			child.LocalTransparencyModifier = child.Transparency
			child:GetPropertyChangedSignal('LocalTransparencyModifier'):Connect(function()
				--if child.Name ~= head then
				child.LocalTransparencyModifier = child.Transparency	
				--end
				
			end)
		end
	end
	
	elseif module.VRvisibilitymode == 'Rec' then
		
		for i, child in pairs(character:GetChildren()) do
			if child:IsA('BasePart') and child.Name ~= 'Left Leg' and child.Name ~= 'Right Leg' and child.Name ~= 'Torso' then
				wait(0.1)

				child.LocalTransparencyModifier = child.Transparency
				child:GetPropertyChangedSignal('LocalTransparencyModifier'):Connect(function()
					--if child.Name ~= head then
					child.LocalTransparencyModifier = child.Transparency	
					--end

				end)
			end
		end
	end
	
	
end

PreparePlayerForVR()


local function VRUPD(Determination : number)
	
	camera = workspace.CurrentCamera
	
	
	--print(camera.CFrame)
	camera.HeadScale = module.headsize
	--print(Determination)
	
	--[[ Get the players headset and controllers]]--
	
	local Headset = vrsrvice:GetUserCFrame(Enum.UserCFrame.Head)
	local leftcontroller = vrsrvice:GetUserCFrame(Enum.UserCFrame.LeftHand)
	local rightcontroller = vrsrvice:GetUserCFrame(Enum.UserCFrame.RightHand)
	local floor = vrsrvice:GetUserCFrame(Enum.UserCFrame.Floor)
	----------------------------------------------------------------------

	--[[define the offsets and stuff like that]]--
	
	local rotationoffset = module.rotationoffset
	local offset = module.armsoffset
	--------------------------------------------------------------------------
	currentpos = Headset.Position --The current position of the head
	
	local difference = currentpos - oldpos --This is the difference in position from the last frame to this one
	--print(difference.Magnitude)
	
	
	oldpos = currentpos --make the old position take over the new one
	
	leftarm.CFrame = camera.CFrame * leftcontroller * offset * rotationoffset 
	rightarm.CFrame = camera.CFrame * rightcontroller * offset * rotationoffset 
	head.CFrame = camera.CFrame * Headset 
	
	--vrsrvice:RecenterUserHeadCFrame()
	
	local cdiff = CFrame.new(difference) 
		
	root.CFrame = cdiff * root.CFrame  --keeps the players body under the head
	
	
	----------A bunch of failed attempts to make the camera move with the body without going back to square one----
--	local currentcam = camera.CFrame.Position
	--local newcam = currentcam - cdiff
	--camera.CFrame = root.CFrame * module.bodyoffset * cdiff
	
	--camera.CFrame = root.CFrame * module.bodyoffset 
	
		--camera.CFrame = camera.CFrame - Vector3.new(cdiff, cdiff, cdiff)
-------------------------------------------------------------------------------------------------------------------
end


vrconnect = RNS.RenderStepped:Connect(VRUPD)


local function vrplayerdied()
vrconnect:Disconnect()
	leftarm.Massless = false
	rightarm.Massless = false
	head.CanCollide = true
	torso['Left Shoulder'].Enabled = true
	torso['Right Shoulder'].Enabled = true 
	torso['Neck'].Enabled = true
end

humanoid.Died:connect(vrplayerdied)	
	
else	
	print(character, 'Is NOT in vr')
end

-- remember to dont let players be able to stick their heads through walls, just have it push them back
1 Like

Hey have you tried using VRService.AvatarGestures (VRService | Documentation - Roblox Creator Hub) as I believe this is what your trying to do.

So i enabled avatar gestures on my R6 script and miraciously IT ACTUALLY WORKED, thank you
(However comes with some pretty MASSIVE issues so ill have to not use it)

At first I thought we were on totally different pages, but I genuinely had no idea that AvatarGestures came with positioning in the games space


Truly thank you (Now all i have to do is not let players stick their heads through the walls)

Edit: Avatar gestures causes a multitude of problems so im not gonna use it.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.