Adding a position offset to a force towards an object

So I’m re-creating Amnesia, simply for educational purposes, the only reason I am mentioning this is because of the physics. I don’t know how Frictional Games did it exactly, but they achieved a really good looking method of “holding” rigidbodies and having them still collide with others, while being able to rotate and adjust distance at the same time.

What I’ve made works pretty much the same - When you grab an object, the script saves the initial position and rotation onto 2 other game objects, and a CoRoutine then interpolates the rotation. This lets me smoothly rotate and move the object. In the CoRoutine (while holding), I am calculating a vector that points towards the initial grab point and is scaled by the distance of the two, making it float nicely to the center while still being pushed away/pushing other objects. The concept is very simple:

//phys_dragger_pos is the initial position - drag_reference is the held rigidbody
Vector3 vel = ((phys_dragger_pos.position - drag_reference.transform.position).normalized);
drag_reference.rigidbody.AddForce((vel * (Vector3.Distance(phys_dragger_pos.position, drag_reference.transform.position))), ForceMode.Impulse);

But when I grab an object, since I am just adding it to the rigidbody, it’s adding the force to the root objects position. So instead of it not moving until I drag it, it brings the base of the object to the initial position. I have tried calculating an offset vector to add to the AddForce function but I’m not very good at math. I have access to the RaycastHit and all information for every object involved. How would I go about adding a position offset to the AddForce function so that it brings the very point I grabbed to the initial position I saved?

Here’s a .gif to show what I mean about the base position:

What is this?

The pink thing is just the rotation reference that it interpolates to.

Hmm not sure if I’m understanding your problem correctly.

So I’m assuming you are using a RaycastHit to get the position you want to use for the offset like:

rayVector = rayHit.point

So if you have the object position:

pickUpObjectTransform.position;

And the ray position:

rayVector;

You should be able to calculate the distance between those points. That’s the calculation you need right? I’m not sure if you have that yet assuming you do.

Seems complicated but I think you might need to create or move a new gameObject at the rayvector position every time you pick something up. Than you could make that object be the parent of the object you pick up. That would allow the picked up object to use transform.localPosition and transform.localRotation so it should maintain the correct position and rotation in relation to the spot you hit with ray.

Hmm I’m having trouble explaining this and I’ve never tried it personally. But basically I’d try to make your pick up objects temporarily a child of the position your ray hit, and you might want to make the position your ray hit a child of the player?

So hierarchy would be like:

  1. Player Object is parent object

  2. Player’s “hand” is child object to player object

  3. The new rayHit.point position is a child to the “hand”

  4. the object being picked up is a child to the rayHit.point

That’s my best guess at how I would attempt this, but that’s just kinda a guess this problem sounds pretty complicated to me.