x


detecting taps on 3d objects in iOS

Having trouble with this, and can't find a working example. I have 5 objects, that need to detect when they are tapped, this code seems to detect the taps if I place it on the objects, but picks up the tap anywhere on the screen, at the same time for all 5 objects! Any clues on how to just detect if the tap is on one object?

private var hit : RaycastHit;
private var ray : Ray;
var titleCamera : Camera;

function Update () {

if(Input.touchCount == 1) {
        var touch: Touch = Input.touches[0];
        ray = titleCamera.ScreenPointToRay(Input.touches[0].position);
        if(touch.phase == TouchPhase.Began && Physics.Raycast(ray.origin, ray.direction,hit)){
            //do something for this object
        }
}

The 3D objects have rigidbodies and colliders.

more ▼

asked Jul 11 '11 at 04:56 AM

hawken gravatar image

hawken
91 18 24 25

(comments are locked)
10|3000 characters needed characters left

6 answers: sort voted first

You can add another set of conditionals to check if the hit object is the one you want. By the way do not add this script to the objects, add it to an empty game object. Each instance of this script sends a new ray so with one tap you are sending a lot of rays for that frame right now.

switch(hit.collider.name){
    case "YourObjectName":
        //Do something
    break;
    case "AnotherObjectName":
        //Do something more
    break;
    //and so on...
}
more ▼

answered Jul 11 '11 at 12:17 PM

Sarper Soher gravatar image

Sarper Soher
1.6k 1 4 16

(comments are locked)
10|3000 characters needed characters left

Here is a clean way to get touch events on individual Game Objects without any switch. (my example use C#). The way I used is to create a script managing the Update(), getting which object is touched, and calling the MonoBehaviour script from the object itself. As I use Input component from Unity, it works on Desktop and iOS. The example use a sprite from 2DToolkit but can be applied to any GameObject type I believe...

1) Create an empty GameObject 2) Create a script called touchableManager and attach it to the empty game object. Here is the script:

using UnityEngine;
using System.Collections;

public class touchableManager : MonoBehaviour
{

 protected GameObject touchedObject;
 private RaycastHit hit;

 // Use this for initialization
 void Start ()
 {

 }

 // Update is called once per frame
 protected virtual void Update ()
 {
 if (Input.GetMouseButtonDown (0)) {
 Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
 if (Physics.Raycast (ray, out hit, 100.0f)) {
 touchedObject = hit.transform.gameObject; 
 touchedObject.GetComponent<touchableGameobject>().Touched();
 }
 else {
 print("GetMouseButtonDown on nothing");
 }
 }
 }
}

3) Create a script called touchableGameobject, here is the code:

using UnityEngine;
using System.Collections;

public class touchableGameobject : MonoBehaviour
{

 tk2dSprite sprite;

 // Use this for initialization
 void Start ()
 {
 sprite = GetComponent<tk2dSprite>();
 print ("start mousemanager for "+sprite.name);
 }

 void OnMouseDown ()
 {
       print("Received a mouse down on "+sprite.name);
 }

 void Update ()
 { 
 }

 public void Touched()
 {
 }
}

4) Attach this script to all your game objects!

more ▼

answered Jul 26 '12 at 09:38 AM

DavidCBox gravatar image

DavidCBox
16 1

(comments are locked)
10|3000 characters needed characters left

heres the final code for those interested. Would still be interested in a bit of code that could be applied to individual objects though, tried out some other things, made sense in code but didn't work. Anyhow:

var myCamera : Camera;
var hit : RaycastHit;
var ray : Ray;

function Update () {
    if(Input.touchCount == 1) {
        var touch: Touch = Input.touches[0];
        ray = myCamera.ScreenPointToRay(Input.touches[0].position);
        if(touch.phase == TouchPhase.Ended && Physics.Raycast(ray.origin, ray.direction,hit)){

            switch(hit.collider.name){
             case "object01":
                 Debug.Log("Object01 tapped");
                 //things
             break;
             case "object02":
                 Debug.Log("Object02 tapped");
                 //things
             break;
         }
        }
        else if (touch.phase == TouchPhase.Ended && !Physics.Raycast(ray.origin, ray.direction,hit)) {
            Debug.Log("tap cancelled");
        }
    }
}

this only works when the user lifts up their digit, sausage, whatever, without leaving the confines of that objects area, if they change their mind and slide their tap away, it reports the tap as cancelled.

more ▼

answered Jul 12 '11 at 08:45 AM

hawken gravatar image

hawken
91 18 24 25

Doesn't work, It says that the array index is out of range.

Feb 06 '12 at 01:40 PM MithosAnnar
(comments are locked)
10|3000 characters needed characters left

Sure, create a new script named InputManager and fill it out as below. Then create a new Empty Game Object and name it InputManager just so you can find it later on in your scene and add this script to this GameObject.

private var touchRay : Ray;
private var touchHit : RaycastHit;

var inputCamera : Camera;

function Awake(){
    if(!inputCamera){
        inputCamera = Camera.main;
        Debug.Log("No camera defined for " + this + " . Main camera is being used now.");
    }
}

function Update(){
    UpdateTouchInput();
}

function UpdateTouchInput(){
    if(Input.touchCount == 1){
        var touch : Touch = Input.touches[0];

        if(touch.phase == TouchPhase.Began){
         touchRay = inputCamera.ScreenPointToRay(touch.position);

         if(Physics.Raycast(touchRay, touchHit)){
          switch(touchHit.collider.name){
              case "object1":
                 Debug.Log(touchHit.collider.name + " is hit.");
              break;
              case "object2":
                 Debug.Log(touchHit.collider.name + " is hit.");
              break;
              case "object3":
                 Debug.Log(touchHit.collider.name + " is hit.");
              break;
          }
       }
        }
    }
}

BTW I haven't tested this so my apologies if there are any typos or syntax errors.

more ▼

answered Jul 12 '11 at 09:05 AM

Sarper Soher gravatar image

Sarper Soher
1.6k 1 4 16

(comments are locked)
10|3000 characters needed characters left

well I finally got it working, here is my final script (badly commented) I hope people can use it.

var studioBlock : Transform; // blocker behind the door to stop you entering a room
private var doorObject : GameObject; // the door gameobject (has a collider)
var doorName = "stdr"; // name of the door gameobject
private var Telefoon : GameObject;
var telName = "ipod touch";
private var hit : RaycastHit;
private var ray : Ray;
private var doorOpen : boolean = false;

var inputCamera : Camera;


function Start(){

doorObject = GameObject.Find(doorName);
Telefoon = GameObject.Find(telName);

}

function FixedUpdate (){
    if (Input.touchCount == 1) {
       var touch : Touch = Input.touches[0];

       if(touch.phase == TouchPhase.Began){
       print("tap");
       ray = inputCamera.ScreenPointToRay(touch.position);

         if(Physics.Raycast(ray, hit)){
          switch(hit.collider.name){
              case "stdr":
                 if(!doorOpen){
                   doorObject.transform.animation.Play();// plays the door animation
                   studioBlock.position.y = -100;// removes the room blocker
                   doorOpen = true;
                   //Destroy(this);// destroys the script so you can't spam the door
                 }
                 else
                 {
                   print("door is already open");
                 }
              break;
              case "scene phone":
                 print("iphone");
              break;
          }
         }
       }
    }
}

it is attached to a empty game object somewhere in the scene

Dennis

more ▼

answered Dec 08 '11 at 12:45 PM

vengeance92 gravatar image

vengeance92
1 1 1 1

(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x1958
x1528
x39

asked: Jul 11 '11 at 04:56 AM

Seen: 5541 times

Last Updated: Jul 26 '12 at 09:45 AM