Im working on a 2D game for touch platforms. I had originally written it using the “OnMouse” functions that allowed me to pick up, move, and drop objects, which worked exactly how I needed it to, except the problem was that it does not support multitouch.
Heres my original OnMouse functions which is inside the script which is attached to the object to be moved:
Now I have a very vague idea on how multitouch, but trying to get it to work properly is just giving me a huge headache.
Heres what I have in the Update() function of the same script (with the Mouse functions removed of course):
void Update ()
{
if (Input.touchCount > 0) {
switch (Input.GetTouch (0).phase) {
case TouchPhase.Began:
pickedUp = true;
grounded = false;
screenPoint = Camera.main.WorldToScreenPoint (gameObject.transform.position);
gameObject.rigidbody2D.gravityScale = 0;
break;
case TouchPhase.Moved:
if (alive) {
Vector3 wp = Camera.main.ScreenToWorldPoint (Input.GetTouch (0).position);
Vector2 touchPos = new Vector2 (wp.x, wp.y);
if (collider2D == Physics2D.OverlapPoint (touchPos)) {
transform.position = touchPos;
}
}
break;
case TouchPhase.Ended:
gameObject.rigidbody2D.gravityScale = 2;
pickedUp = false;
break;
}
}
Now, the main problems I am running into with the above code:
First off, multitouch doesnt even work. i can pick up a single object, but if i try to pick up a second object, it seems nothing happens at all.
The object is able to be picked up, but if I move my finger too fast, then the object just returns to normal, almost where it started as if i never even touched it. This did not happen with the OnMouse functions and I was able to move as fast or as slow as I wanted.
When I pick up one object, all the other objects on the screens variables change. So if i pick up one object, i am able to move it, but all the others THINK they are picked up as well because the pickedUp bool is changing on all of them instead of just the one that was touched. Now I THINK I need to do something with fingerId to fix this, but dont have a clue where to begin with that.
There seems to be a significant amount of multitouch tutorials out there, but mostly for buttons and not necessarily moving objects and the ones that are for moving objects seem to be using Raycast which (to my understanding) doesnt work the same when working with 2D, which may be where I am getting lost…?
Anyone with multitouch and 2d experience have any insight for me?
Ok I understand the multitouch a little more. So i guess I should be creating a new script attached to an empty game object rather then running it in the script attached to the object im trying to move, correct?
Any suggestions on checking to see if the touch point is over the object? Since I was running the touch checks on the object itself, it allowed me to pick up the object using “transform”, so I wasnt doing any checking to see what object i was over. And I realize that the touch position is different than the world position, so any suggestions on the easiest way to get that working?
You can do it in one of two ways - you can raycast for the object (bring the 2D screen position into 3D space), or you can bring the 3D position into 2D Camera space and use a simple “inside the circle” distance check. Both have their advantages; raycasting is simpler and automatically accounts for scale, shape, and distance, while flattening (using Camera.WorldToScreenPoint) allows you to make the touch target any size (which is really good for touchscreens!).
I believe the docs pages for Physics.Raycast and Camera.WorldToScreenPoint have examples that should get you most of the way to accomplishing this.
Your biggest challenge in this script (I wrote basically the same script not 2 weeks ago; unfortunately it’s developed under NDA and not mine to share, or I would) is going to be keeping track of multiple taps simultaneously, and across frames. You can’t simply have one “holdingRigidbody” variable in this script, because you could be holding several rigidbodies, and you have to be able to associate each rigidbody with the correct fingerID. I used a Dictionary for mine, with fingerID as the key and rigidbody as the values.
You might be able to keep your “drag” script on the individual objects; each one will have to store the fingerID of the touch that picked them up when they get picked up. I’m not entirely sure how that script would be structured beyond that though.
Hold on a tick… isnt that what I am doing here???
Remember, Im using 2D physics and not 3D which I think is helping confuse me even more lol
But again, I think this works because I have the script attached to the gameObject itself. If I make a seperate script and attach to an empty object (for multitouch), then Im still dead in the water…
I’ve faced same question making my game and decided to make an universal script that will get rid of any bicycle inventions again and again, and at the same will be very simple and mimic OnMouse events. I’ve submitted it to Asset Store, hope it will be approved. If so, I’ll let you know.
@yaapelsinko tried PM’ing you, says you have it disabled. Can you provide me more details on what exactly your universal script does? Would definitely be interested if its going to help me
Strange, don’t remember that I’ve disabled it. Maybe it is some kind of post count limitation, I don’t know.
As for script, it makes objects with colliders to receive messages corresponding to touch input events. As I said, its behavior in most part mimics ‘OnMouse’ methods, so there are also 7 of them:
Multitouch is supported so there can be several simultaneous touches (simultaneous drags or UpAsButtons and others). When object receives an message it also receives its ‘own’ touch information. So no need to check what’s going on when objects is updating - when some touch interacting happens, objects will know it.
Hmmm, sounds like its exactly what i need. Any idea how long it takes to get in the asset store? Would you be willing to sell outside the asset store? Really would like to get my project finished up and this is the only thing stopping me right now unfortunately…