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:
The pink thing is just the rotation reference that it interpolates to.