How to make 2 hand VR grabbing?

I am trying to make a grab system for my VR game and it works well with one hand but when I grab with both hands it looks wierd.

Video (Sorry for the clideo watermark I had to edit the video because roblox wouldn’t accept a 12 mb video):


I am using WeldConstraints with part0 being whatever hand is grabbing and part1 being the thing you are grabbing.

I’m not super experienced with VR related development, but from my assumption, the physics engine is trying to handle two conflicting “truths”. You’re welding the same part to both hands so its getting confused on where to position itself.

Just a theory, but you could always try creating an invisible “pivot” part

You position this pivot part at the midpoint between the two hands each frame and orient it so its X-axis (or Z, your choice) points from primary-hand → off-hand

Drive the pivot with a single AlignPosition + AlignOrientation and weld the actual tool to that pivot (one WeldConstraint)

Completely untested though so hopefully someone with more experience has a better idea or way to implement this lol

Ok so I did something similar to what you said but a bit different. I started by disabling the AlignPositions and AlignOrientations in the hands then made a new AlignPosition and AlignOrientation for the part I’m grabbing. I got the midpoint for the lefthand and righthand controller cframe to position the attachment1 of the AlignPosition and AlignOrientation which works great but I am struggling a bit with the orientation.

I am doing the orientation by adding both the left and right controller orientations and dividing that by 2 but it just spins most of the time

1 Like

I’ve looked a bit into it and I believe when you average orientations, it can get a bit confusing for Roblox’s underlying quaternion system (which is what Roblox uses for rotations internally).

I’d say you can try this:

  1. Keep your midpoint calculation for the position, that should work fine
  2. For the orientation, instead of trying to average the raw orientations:
    • Use the vector between hands as your primary direction (this defines the forward axis)
    • For the up vector, use quaternion slerp instead of direct averaging:

I can give you some psuedo code showing it but actual implementation may be a bit different:

local forward = (rightHandPos - leftHandPos).Unit
local midpoint = leftHandPos + (rightHandPos - leftHandPos) * 0.5

-- Create a consistent up vector (you could always use world up or another reference)
local baseUp = Vector3.new(0, 1, 0)

-- Make sure up isn't aligned with forward (which may be the cause of flipping)
if math.abs(forward:Dot(baseUp)) > 0.9 then
    baseUp = Vector3.new(0, 0, 1)-- Alternative up
end

local right = baseUp:Cross(forward).Unit
local adjustedUp = forward:Cross(right).Unit

-- cframe conversion
local orientation = CFrame.fromMatrix(midpoint, right, adjustedUp, -forward)

Then you’d just apply that orientation to your grabbed object with a WeldConstraint

The main thing is your don’t wanna rely on directly combining controller orientations, but construct a stable orientation based on the positions of the controllers

If this is a bit confusing I can try giving a better explanation, I hope this helps out a bit

You can try using ballsocket constraints.

How can I use ball socket constraints for this?

Ok so at first it was flipped but I realized it was because I didn’t orient the attachment0 in the grabbed part. Would I use the same orientation in the code you provided me to orient the attachment0?