- Home /
Drag a ball to add force to a ball by touch screen
I want to make an android game that when you drag a ball, a force will be added to it. If the ball is dragged for a longer distance, the force will be larger. So how do I make the script of the ball, is it using code like TouchPhased.Moved?
Sounds like you're just barely getting started on this. There are lots of examples of moving towards touches, finding touch "speed", using raycasts to see where they are touching on the ground ... . Once you know that stuff, the exact way the ball moves is just program$$anonymous$$g.
Screen touches and mice are pretty similar, and it's much faster and easier to test on a Desktop.
You save the position of the ball when you touch it at the start, then the position of the ball when you release it; you calculate the distance between this two points with Vector3.Distance(), and you use this value in Rigidbody.AddForce()!
trololo: that's for a slingshot? I assumed the ball was going to be guided like a rubber band attached to your finger, but the OP wasn't really specific.
Answer by wibble82 · Mar 20, 2014 at 01:42 PM
Can i make a quick suggestion. With this kind of thing, where presumably the interaction between ball and finger is quite important, its often better to get the physics engine to do the hard work for you.
By this I mean that by just adding forces, you're effectively letting the physics engine simulate a load of bodies, then going 'and by the way heres some extra forces to think about'. That works fine in a simple scenario, but as soon as you want nice joints, or that ball to interact with another object (like a wall) while being dragged, it becomes much less stable. The physics engine has all the equipment to deal with this kind of problem, but if all you're telling it about is random forces then it can't do too good a job!
A more effective approach is to create an invisible, none-collidable, kinematic rigid body that follows the location you want your ball to go to (i.e. where the finger is). Create a spring joint (in code) between your invisible body and the centre of the ball when the player has their finger on the screen, and remove/disable the joint when the player lets go.
This approach means the physics has a genuine understanding about the way you want the ball to move, and can take this into account while processing all the other calculations it does along the way. It also means you don't have to mess about with the maths of forces and stuff!
That's the technique I've always taken with this kind of problem. Much more robust :)
In general, code-tweaking physics can give bad results, but for a single spring, code works pretty well. The math for springs is pretty simple (F=d times spring constant) and FixedUpdate is there for you. It's not like there's an actual spring inside the computer -- the code you can write is the same as the built-in code.
Using code, you can do things like moving at least speed 3; extra drag if it slides past (so it won't bobble); extra drag on the perpendicular velocity (so it won't swing as much); if they have never moved faster than X, just track the position; drag on speed past X (so a huge pull is faster, but not that much); pull from the part of the object they touched. In general, if the pull feels a little funny, code allows more tweaks. I've done it with objects with 3+ hinges, and works fine on them (use code to add force to one segment, then let hinges do their thing.) Even hand-coded angularVelocity changes can look very nice.
But, for 95% of everything, sure, just use a tuned spring.
I have to disagree with "the code you can write is the same as the built in code". This is very not the case! :)
Constraints built into the physics system run as part of the solver, every iteration, in conjunction with all the other constraints (joints and collision data). The basic maths for springs may be the same, but the built in joints are doing much more than just applying forces once per fixed update
Sure, if you don't use a rigidbody, and try to rewrite the entire physics system using translate and rotation. you lose a lot of the "realism."
The idea is, keep the "movee" as a rigid body. Give it joints if you need to. Replace only the drag-spring with coded spring math (mostly AddForce towards the target and velocity*=drag.)
It does seem like a real Unity spring would have some extra magic, but I've been replacing critical springs (need to move in a precise way) with code for a while now. It keeps all the physics goodness.
The problems arise when you are dealing with more than 1 object interacting. A spring is more complex than just Hooke's law spring force. It also involves a drag force based on the velocity of the object (or relative velocity of the 2 objects).
When done inside the solver, within a single 'FixedUpdate', if your solver is set to 10 iterations, the calculations are done 10 times (in native code, so probably still faster than in script).
When all you're dealing with is your object attached to the spring, you will see virtually no difference. However if you pull that object into another rigid body (especially a heavy one) the velocities of the objects involved will change throughout each iteration, as contact constraints are resolved alongside other constraints (such as springs).
As with many of these things, in the simple scenario of just 2 objects you won't see any difference between the solver solution and your custom solution. That'd be true even if you discarded rigid bodies altogether and did all the collision forces yourself. However as soon as you throw multiple bodies into the mix, and end up with 'conflicting' constraints that need an iterative solver to come to the correct solution, the custom solution diverges from the correct solution.
And of course, on top of all that - doing it via the solver is cheaper! And on a mobile that's important :)
If it helps, imagine using a one time velocity=Vector3.up*20
on a rigidbody. Code launched it, but the physics engine gladly has it bounce, spin, slide, transfer momentum into multiple objects, and so on. You can give it joints, and they work as normal.
If you ins$$anonymous$$d use 30 frames of velocity+=Vector3.right*Time.deltaTime;
, code accelerates it, but it still does all the physics stuff. Likewise velocity.x*=0.99f;
every frame on a rigidbody gives it fake left-right drag, but won't affect any other normal physics interactions.
A single "code-based spring" is just a combination of those tricks.
Your answer
Follow this Question
Related Questions
Three finger tap? 1 Answer
Touch Input madness 2 Answers
Problem with touch button (when moved) 2 Answers
Processes two touches instead of one 0 Answers
smooth movement with rigidbody2D 1 Answer