What's the best way I can go about making VR objects held by 2 hands?

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!
    Having a object in VR held by both of the users hands without it being too glitchy.

  2. What is the issue? Include screenshots / videos if possible!
    At the moment I am using an AlignPosition/Orientation for the main grabbing hand but for the second hand, I weld it. This causes problems as it isn’t too accurate and seems to be behind, I am happy if I would have to change how I do my grab script entirely as it isn’t that good right now.

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I have tried both hands using AlignPosition/Orientation and both hands using Welds but they both make the item disappear.

I’m not sure of the cleanest way to handle this, but I’d:

  • treat both handles as balls/positions to attach the tool to
    • ignore the rotation of the hands
  • primary hand (probably right hand) attaches to a point on the tool with a ball-in-socket-like connection
    • the point would either be preset, or wherever the hand grabs onto the tool initially
  • the other hand (probably left hand) attaches to a point on the tool that can both rotate freely, and slide along the tool like I think a SlidingBallConstraint
    • I havent used that constraint, but I’m assuming it’s a mix of BallInSocket and Prismatic

shown below, the primary grip (blue) is aligned to one position and can rotate freely,
and the secondary grip (red) is aligned to a point that slides along the tool, and can rotate around that point


also note that the secondary grip should also be constrained to the length of the tool or the length from one end of the tool to before where the primary grip is

edit, I’ve made another diagram with more detail

Alright ill try using this example, hopefully, it will work as I cant find any way to do it otherwise. Also, I don’t know if I didn’t read it right but what would I do for rotation I want the item, aka a sniper, to be rotated right.

I have tried this and it didn’t seem to give the effect I wanted, however, this could work in some applications.

in that case, maybe rely only on the position and rotation of the primary hand to orient the tool, then check if the other hand is about where the grip is with some leeway
if the secondary hand is too far, then trigger some “tool isnt being held properly” function
if the secondary hand is in range, then snap the hand onto the tool

I’ll try something like this. Hopefully this works.

Bumping this up because I still didn’t get a solution.

I can’t post a comment, so I’ll write my thoughts as an answer.

Using alignPosition/Orientation is not a good idea, as these nodes are designed to control rotations, not positions. You can use them anyway, but they will always have an offset.

Using Weld is not a good idea either, as it will lock the position of the second hand.

My suggestion is to use the velocity of the first hand, to translate the object along the velocity vector. Each frame, multiply the velocity of the first hand by the time delta. And move the object by that amount.
const object = workspace.object; // the object you want to move
const hand1 = workspace.hand1; // the first hand

const translation = hand1.Velocity.mul(Time.deltaTime());
object.Position = object.Position.add(translation);

The second hand position can be used to add an offset to your object.
const offset = hand2.Position.sub(hand1.Position);
object.Position = object.Position.add(translation).add(offset);

Alright, I’ll try this. I will do it later though as I am rewriting my system to make it easier to use.

None of this code works in LUA, or at least Roblox LUA.

don’t copy it verbatim, translate it to lua

local object = workspace.object -- the object you want to move
local hand1 = workspace.hand1 -- the first hand
local hand2 = workspace.hand2 -- the second hand

local rs = game:GetService("RunService")

-- assuming that everything below this comment should be ran via renderstepped or presimulation

rs.PreSimulation:connect(function(delta)
     translation = hand1.AssemblyLinearVelocity * delta -- .mul means to multiply, other languages have 
     functions for this instead of Lua just using operators
     object.Position = object.Position + translation -- same thing but with addition

     offset = hand2.Position - hand1.Position -- same thing again with subtraction
     object.Position = object.Position + translation + offset -- once again addition
end)

Yeah, I just didn’t get the .mul and Time.deltaTime(). Thanks for converting it by the way. I will also try this soon.

1 Like