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
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:
Keep your midpoint calculation for the position, that should work fine
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
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?