- Home /
Can I have a rigidbody continue to calculate physics while being dragged by code?
EDIT2: I was having more difficulty than I should have getting this to work in my game so I set it aside for a while and came back to it and got it to work in 15 minutes. The solution that worked for me was to use a Spring Joint, not a Fixed Joint like the selected answer says.
EDIT: Edited title to remove extra question mark. No idea why, but while typing in the question field in Firefox the entire box gets covered by a black rectangle so I missed the typo.
In my game I have 3D objects being dragged along a 2D plane via touch position, and when the touch ends I want to throw the object with the same velocity/direction of the drag.
Keep reading.
While being dragged by code the rigidbody still has collision and all that fun stuff, but it doesn't do any velocity calculation (I know why, (Unity Physics only calculate when moved by physics forces) but I want to make a work around.)
My first solution was to calculate direction and velocity based on position the tick that the object is let go (touch release) and the tick immediately before (previousPosition), but obviously this calculates based off of positions over 1/30th of a second, so to players it seems unpredictable.
I'm currently working on a solution that stores positions over time, but to do that accurately I need to check and compare each position and only do the final calculation based off of positions that are along a similar path, and I already know this won't feel quite right either. (Not to mention it is complicated...it involves calculating velocity and direction between each position in the array and discarding bad values (if they stray too far from the average velocity/direction discard those values. I feel that this way would be more accurate than my first solution, but that it's also too complicated for a relatively simple action.)
Is there a way that the object being dragged can calculate this automatically with Unity's physics?
If not, is there a better solution to this problem that someone could recommend? I've been mulling over this one for a few weeks now and have yet to have an epiphany.
EDIT: I accidentally a comma.
I already have collision interaction between other objects while it is being dragged around, I'm trying to find a better way to THROW the object based on the speed and direction it is dragged.
Well that certainly sounds easy, and it takes probably a twentieth of the processing time of my confounded second solution.
I'll start on that in just a bit and report in my findings!
Alright, so writing the functions to do the calculation you suggested was easy enough, but I'm having trouble applying it to my object.
In the game is a dragObjectArray of all objects being dragged, and there is a dragIndex that lets me easily reference which object in the array I want to specify, but obviously arrays don't have deltaTime or deltaPosition.
The dragObjectArray code we've been using works fine, but I can't find a way to convert that to the appropriate index for Input.touches...any idea how I might be able to do that?
I upvoted your answer in the thread you linked :p
But no, that isn't what I mean - I remember you giving me that advice in another question a few weeks ago though, haven't forgotten it!
I usually use lists myself, but I'm not the one who wrote the dragObject code.
$$anonymous$$y problem: I can't access the deltaPosition/deltaTime of the object. I know what object is being dragged, but I don't know how to find the index (Input.touches[index]) from there.
Right now I'm working on using WorldToScreenPoint to convert the dragObject's position into 2D screen coordinates to compare against each Input.touches[index].position until I find it, but I have to make a slight workaround of existing code before I can test that.
Answer by JanWosnitza · Oct 16, 2012 at 04:14 PM
An easy way is to connect the rigidbody with another rigidbody via a fixed joint und just move the other object in FixedUpdate. This enables you to have full collision-detection.
I'm trying this solution now, and my problem now is that I can't get the FixedJoint to break!
When I want the held object (while held it is set as the FixedJoint's connectedBody) to be thrown, I set the break force to 0 and then add force (0f, 1f, 0). The Editor shows that breakForce has been changed, but the force doesn't break the joint.
Alright, well first setting the connectedBody to null wouldn't detach the attached object and would throw an assertion, so I switched to trying to break it by adding force and that didn't work, so I switched to trying to break it by adding torque and THAT wouldn't work, so on a whim I tried setting the connectedBody to null again and for no reason now it works.
So now I can detach it from the Joint, but it doesn't have any velocity afterwards other than what it gets from gravity.
Do as Fattie said :)
$$anonymous$$y post was meant as a general way to achieve your goal, so don't hesitate to try a spring!
Answer by Owen-Reynolds · Oct 16, 2012 at 05:33 PM
Your "average position" idea isn't that bad to write. Use a weighted average to adjust speed and direction towards current frame:
speed = Mathf.Lerp(speed, speedThisFrame, 0.3f);
dir = Vector3.Lerp(dir, dirThisFrame, 0.3f);
Where you're already computed speedThisFrame and dirThisFrame. The 0.3 is how quickly it adjusts to changes in direction (like a 1-frame sideways flick at the end.)
Another way to do it is to use physics for the finger drag. Instead of setting position, use physics to "push" the object towards your finger. When it gets close, chop the velocity way down (to avoid bobbling.) Not super-easy to do, but can look really pretty. When you stop dragging, the object will naturally keep flying.
Fattie: to be able to update the 10th last position, you need to keep and update a list of the last ten (since the 9th previous becomes the 10th previous next frame.) Weighted average sort of "remembers" all the old values, using one extra var.
Your answer
Follow this Question
Related Questions
Touch controlled ice puck 0 Answers
Throwing object with force 1 Answer
Drag a rigidbody2D around scene 2 Answers
Drag and throw Rigidbody2d? 3 Answers
How to negate this force? 2 Answers