VR hands not working

So, I’ve been trying to make some VR hands, like the ones you’d see in job simulator.
For some reason, they won’t appear, even though they do seem to be going to their correct positions.
I’m not really sure what is happening and I’d like something to make sure I’m not being an idiot here.

My script:

local UserInputService = game:GetService("UserInputService")
local VRService = game:GetService("VRService")
if VRService.VREnabled == true then
	warn("VR is enabled")
	local ReplicatedStorage = game:GetService("ReplicatedStorage")
	local Hands = ReplicatedStorage:WaitForChild("oculusHands"):Clone()
	local handL = Hands:WaitForChild("handL")
	local handR = Hands:WaitForChild("handR")
	Hands.Parent = script.Parent
	handL:SetPrimaryPartCFrame(VRService:GetUserCFrame(Enum.UserCFrame.LeftHand))
	handR:SetPrimaryPartCFrame(VRService:GetUserCFrame(Enum.UserCFrame.RightHand))
	local Track = function(Input, Value)
		print(workspace.CurrentCamera.CFrame.Position)
		print(Value.Position)
		if Input == Enum.UserCFrame.LeftHand then
			handL:SetPrimaryPartCFrame(Value)
		elseif Input == Enum.UserCFrame.RightHand then
			handR:SetPrimaryPartCFrame(Value)
		end
	end
	VRService.UserCFrameChanged:Connect(Track)
else
	warn("VR is not enabled")
end
5 Likes

Out of curiosity, what is script.Parent equal to? It’s almost too obvious that it’s workspace, but I want to make sure, because this line right here:

Hands.Parent = script.Parent

looks like the biggest culprit.

1 Like

The localscript that is calling this event is in the StarterCharacterScripts.

1 Like

Ah. I got them to show now. They were parented to a first person character. Now my only problem is that they don’t follow the CFrame of the controller.

1 Like

Could you explain this in more detail? How is it not following the CFrame of the controller, and what is the controller in the first place?

1 Like

They are hands that are supposed to be following the player’s controllers (left, right oculus controller) and track them. Parenting them to the workspace now gets them to show, but they aren’t “tracking” the player’s hands.

1 Like

So you mean the hands are frozen in place and not moving, or is it lagging behind the player’s real hands, or something else like that?

1 Like

You are correct. I have fixed that issue though, but I have encountered another.
My issue is now that whenever I use the thumbstick to rotate my camera, they don’t follow it.
Proof:
https://gyazo.com/fcd5d23e8def96b3f93b6a1c3f689798
My updated code:

local UserInputService = game:GetService("UserInputService")
local VRService = game:GetService("VRService")
local CurrentCamera = workspace.CurrentCamera
if VRService.VREnabled == true then
	warn("VR is enabled")
	local ReplicatedStorage = game:GetService("ReplicatedStorage")
	local Hands = ReplicatedStorage:WaitForChild("oculusHands"):Clone()
	local handL = Hands:WaitForChild("handL")
	local handR = Hands:WaitForChild("handR")
	Hands.Parent = workspace
	handL:SetPrimaryPartCFrame(VRService:GetUserCFrame(Enum.UserCFrame.LeftHand))
	handR:SetPrimaryPartCFrame(VRService:GetUserCFrame(Enum.UserCFrame.RightHand))
	game:GetService("RunService").RenderStepped:Connect(function()
		handL:SetPrimaryPartCFrame((VRService:GetUserCFrame(Enum.UserCFrame.LeftHand) + CurrentCamera.CFrame.Position) * CFrame.Angles(0,  math.rad(180), 0))
		handR:SetPrimaryPartCFrame((VRService:GetUserCFrame(Enum.UserCFrame.RightHand) + CurrentCamera.CFrame.Position) * CFrame.Angles(0, math.rad(180), math.rad(180)))
	end)
else
	warn("VR is not enabled")
end
1 Like

It looks like this CFrame is already relative to the camera and fixed in global space. This should be easily fixed by just multiplying the CFrame returned from :GetUserCFrame or .UserCFrameChanged by the camera’s CFrame:

local camera = workspace.CurrentCamera

local function Track(Input, Value)
	print(camera.CFrame.Position)
	print(Value.Position)
	if Input == Enum.UserCFrame.LeftHand then

		-- made changes here
		handL:SetPrimaryPartCFrame(camera.CFrame * Value)

	elseif Input == Enum.UserCFrame.RightHand then

		-- and here specifically
		handR:SetPrimaryPartCFrame(camera.CFrame * Value)
		-- accidentally misspelled "camera", lol
	end
end

VRService.UserCFrameChanged:Connect(Track)

If this does not work, you might need to something like saving the head’s CFrame somewhere every frame and multiply the hand CFrames by that.

2 Likes

With a little bit of tweaking, I was able to get this to work.
Thank you for helping me and making me understand VRService a bit more.
Here’s the full code for anyone that wants it:

local UserInputService = game:GetService("UserInputService")
local VRService = game:GetService("VRService")
local CurrentCamera = workspace.CurrentCamera
if VRService.VREnabled == true then
	warn("VR is enabled")
	local ReplicatedStorage = game:GetService("ReplicatedStorage")
	local Hands = ReplicatedStorage:WaitForChild("oculusHands"):Clone()
	local handL = Hands:WaitForChild("handL")
	local handR = Hands:WaitForChild("handR")
	Hands.Parent = workspace
	handL:SetPrimaryPartCFrame(VRService:GetUserCFrame(Enum.UserCFrame.LeftHand))
	handR:SetPrimaryPartCFrame(VRService:GetUserCFrame(Enum.UserCFrame.RightHand))
	game:GetService("RunService").RenderStepped:Connect(function()
		handL:SetPrimaryPartCFrame((CurrentCamera.CFrame * VRService:GetUserCFrame(Enum.UserCFrame.LeftHand)) * CFrame.Angles(0, math.rad(180), 0))
		handR:SetPrimaryPartCFrame((CurrentCamera.CFrame * VRService:GetUserCFrame(Enum.UserCFrame.RightHand)) * CFrame.Angles(0, math.rad(180), math.rad(180)))
	end)
else
	warn("VR is not enabled")
end
4 Likes

Will I need to rig the hands?
( 30 charrrrrrr )

If you want to track finger movement, you’d need to rig the hands.