- Home /
Scripting a "touch" on an object in iOS.
I'm sure this is a simple fix to most of you but I have been racking my brains out trying to figure it out.
I am working on a first person game and I want to be able to change scenes when the player comes to a door (cube) and touches it with his finger. I have been working on this script:
function Update (){
if(Input.GetMouseButtonUp(0))
{
Debug.Log("I touched the wall!"); //I will be changing the Debug.Log to a
// scene change when it is working properly.
}
}
but all I seem to get is a printout in the console every time the player's finger is taken off the screen... no matter what he touches. I would like it to happen only when the player touches a particular cube that looks like a door.
I would really appreciate any help that anyone may be able to supply. Thanks so much.
Tom
Answer by Hendrys · Dec 30, 2011 at 12:15 AM
Don't omit the RayCast part, it's important. A ray is a mathematical (invisible) line. In this case this ray is calculated based on the touch's position and the camera's projection using the function ScreenPointToRay. This function "projects" the point (in the device's 2D screen) to a Line in the world, starting from the Camera's position and until it reaches 100 units "into" the device.
function Update () { for (var touch : Touch in Input.touches) { if (touch.phase == TouchPhase.Began) { //Here you have the touch's position so, This is where you have to create a ray using ScreePointToRay var userRay = Camera.main.ScreenPointToRay(touch.position) ; //This is to store the RayCasting results var info : RaycastHit ; //[Physics.RayCast][2] actually casts the ray and if it returns true it "Hit" something if(Physics.Raycast(userRay, info, 100.0f)) { //This tells us if the thing it hit was a "Door". if(info.transform.CompareTag("Door")) { // This is where you have to put the change level info Debug.Log ("I touched the door!"); Application.LoadLevel ("Level2");
}
}
} }
}
It looks awful and tedious but that's what you have to do to hit something. Also, this looks terrible becasue the comments, but you can do it cleaner if you prefer. But please do not take away the Raycast part.
@Lo0Nuhti$$anonymous$$, I believe @Hendrys was talking about me. I left out the Ray section because I wanted to try to see if I could get a simple touch to work if I put the script on the cube itself. Well, it didn't work, of course. I also wasn't sure hot to incorporate both the touch and the ray in the script.
@Hendrys, I coded exactly as you posted and I received a "touchRange" error in the script for the line if(Physics,Raycast(userRay, info, touchRange)). Am I missing a variable? I don't know why I am getting this error, now.
I am so sorry for being such a pest but I am so close to finishing this game. When I'm done, I promise to learn all about rays... and as much about scripting as I can. LOL.
Thanks so much for your help! $$anonymous$$
YOU GUYS ARE AWESO$$anonymous$$E! It is working and I can't thank you all enough!!! @Hendrys, @Lo0Nuhti$$anonymous$$, and @crazy$$anonymous$$night! Thank you so much. I can't tell you how much this means to me. I'm off to learning so much more about Unity and scripting. I hope I can help you guys some time in the future. And thanks for being so patient with me.
$$anonymous$$
Also, thank you for guiding me through the proper etiquette of the Unity Answers and all its tricks. I truly appreciate it.
@Hendrys.. I really appreciate you answer but I wish i could get the same in C# script way.. anyway Thanks.
Answer by Hendrys · Dec 27, 2011 at 11:58 AM
The problem is in IOS you don't have a Mouse, you have to use input.GetTouch(). Then you have to get the position of that touch with input.GetTouch().position. Then you have to Cast a Ray from the User's perspective (the camera) to that position in the World (using Camera.SreenPointToRay() )
And then test if the Ray hits the Cube (door).
If that happens then you change the scene
Try this:
//A Vector to store the touch position
Vector2 userClic;
//If the user has touched anywhere...
if(Input.touchCount > 0)
//Then, store the touch position
userClic = Input.GetTouch(0).position;
//Create a ray base on the camera's position and the userClic
Ray userRay = Camera.mainCamera.ScreenPointToRay(userClic);
//an object to store the ray cast info
RaycastHit info;
//If the ray hits any object...
if( Physics.Raycast(userRay,out info, 100))
{
//If that object is a Door (You have to label the object "Door")
if(info.collider.tag == "Door")
{
//Here you open your door i.e. change the scene...
}
}
Hope it helps...
@Lo0Nuhtik, Thank you for the translation. It seemed to look right as far as formatting. I put it in and received an "ArgumentException: You are not allowed to call INTERNAL_CALL_ScreenPointToRay when declaring a variable." I'm sorry but I am not familiar with "Rays" yet to fix this myself. Any help would be appreciated. Thanks so much. $$anonymous$$
Answer by crazyKnight · Dec 27, 2011 at 08:55 AM
var hit: RaycastHit;
var ray;
function Update ()
{
if(Input.GetMouseButtonDown(0))
{
if (Physics.Raycast (ray, hit, 100))
{
if(hit.collider.gameObject.tag == "Door") // tag your cube with the name Door
{
// write in your code here
}
}
}
excuse me, why my answers aren't appearing at all? Could you moderate them? do you have enough karma?, thanks a lot.
I'm terribly sorry but I don't understand why your answers aren't showing up. I don't believe I have any control over that. I'm relatively new on Unity Answers so I don't have much karma. I don't know if it is about my karma or yours. I'm sorry I can't help in this but thanks for trying to help me. I appreciate it.
Dear crazy$$anonymous$$night, I put in the name of the door in the tag of the cube under Element 0 and dragged the script onto the cube that is the door. When I remotely played the game to see if the script worked, I received an error in the console stating "NullReferenceException: Object reference not set to an instance of a TouchTest.Update() (at Assets/TouchTest.js:9). Did I do something wrong?
Dear @Hendrys, I typed in your code suggestion (I think I needed to add the { }s after the "if(Input.touchCount > 0) because they weren't there.) but I couldn't try it because I am getting an error stating that a ';' is expected at line 'Vector2 userClic;' but I already have one there. I'm so sorry to bother you with these little problems but I am at a total loss with this one. Thanks so much for your help. Both you and @crazy$$anonymous$$night.