- Home /
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:
The pink thing is just the rotation reference that it interpolates to.
No, the way I have it working now is how it seems to work in Amnesia. I just need to figure out how to get a Vector3 offset that is basically the distance between the inital point (raycast hit) and the objects initial position, so I can add it to the vel vector making it drag the object from the point that I grabbed it from, ins$$anonymous$$d of the root objects position.
I've tried to make an offset and add it to it but everything I've tried has screwed it up, and it starts shaking for some reason.
Personally I cannot visualize an offset solution like you describe that would solve the problem you describe, but there is a lot I don't know about the physics engine. Typically I see the problem I think you are trying to solve done using hinges. Take a look at the standard DragRigidbody script for example. Another untested idea is to change the center of gravity to the drag point.
Oh yeah I've spent like an entire day messing with that script... No matter what I tried it always seemed like it was dangling from a single point, and whenever I set the spring strong enough to keep it in place it was shaking and jittering :\
I'm gonna keep trying every combination of the math I can think of until it works, though. Thanks anyways!
Answer by RyanZimmerman87 · Oct 28, 2013 at 11:48 PM
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.
Haha yeah, I literally just got it worked a $$anonymous$$ute ago doing what you said without reading it first. I had a position reference game object parented to my camera, and ins$$anonymous$$d of moving it to the raycast position I moved it to the objects base... I was definitely thinking about it way too hard last night. Anyways, I'll mark your answer as correct and up vote it just because you answered :)
Cheers!
Your answer
Follow this Question
Related Questions
Android Moving with finger without breaking physics 0 Answers
add force to object that has 2 different rigid bodies 0 Answers
How to calculate delta offset time between race cars? 0 Answers
Checking if mouse dragged from one point to another 2 Answers
How to calculate force to apply to move object to a certain distance. 1 Answer