x


Ignore Touch

In the mobile 2D game that I'm developing the user touches the screen to shoot. So my code for that is basically:

function Update(){
for (var touch : Touch in Input.touches) {
     if (Input.touchCount > 0 && touch.phase == TouchPhase.Began && Time.time >nextFireTime){
    //Raycast Bullet, Fire Sound, Whatever
    }
  }

Now when I want to do something like open a door I'd touch that and it would open. But the problem is that I also have my function to fire every time the user touches the screen. So whenever the user touches to open a door, touches a gun icon to reload, or anything else in that manner -(I'll call them "None firey stuff" for the sake of this question)- a bullet is fired when It really isn't appropriate to.

So want to have the script not fire when "None firey stuff" is touched but I can't figure it out.

I've tried boolean's that sets to true when the "None firey stuff" is touched but by the time the firebullet script notices it it's to late and the bullet has already been fired.

Then I've tried, and currently working on, using raycasts to ignore layers and only fire when it has hit a layer that is not ignored. Here's what my script basically looks like for that:

for (var touch : Touch in Input.touches) {
 if (Input.touchCount > 0 && touch.phase == TouchPhase.Began && Time.time > nextFireTime) {
    var hit : RaycastHit;
    var ray = Camera.main.ScreenPointToRay (touch.position);
     if (Physics.Raycast(ray,Mathf.Infinity,layerMask2)) { //This part makes sure that the user is touching a "Fire Friendly" area
             //Play Sound
               nextFireTime = Time.time + shotInterval; //nextFireTime and shotInterval is a var 
              if (Physics.Raycast (transform.position, transform.TransformDirection (Vector3.forward), hit, 1000, layerMask)) { //Shoots ray for Raycast Bullet
// If hit Gives damage, instantiates blood, whatever
            }
        }
    }  
}

But this doesn't work either because if the player touches my little gun reload icon, which is a gui element, the raycast doesn't even see it so I get firing while reloading. To try to fix this I tried putting a collider in the position of the reload icon on the screen and put the layer to that of "None firey stuff" but that doesn't work at all.

So, how would you make it so it doesn't shoot when a "None firey" object is touched.

Thank You for the help, you have no idea how much i appreciate it. .......................................................................................................................................................................................................

Edit: Don't have to look at it, just posting it if it helps

I might get asked this later so here's what a fraction of my actual script I'm using for Firing pretty much looks like. :

function FixedUpdate(){
if (alive){
for (var touch : Touch in Input.touches){
        var playerPlane = new Plane(Vector3.up, transform.position);
        var ray = Camera.main.ScreenPointToRay (touch.position);
        var hitdist = 0.0;
        if (playerPlane.Raycast (ray, hitdist)) 
        {
            var targetPoint = ray.GetPoint(hitdist);
            var targetRotation = Quaternion.LookRotation(targetPoint - transform.position);
            transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, rotateSpeed * Time.deltaTime);
            transform.Translate((Vector3.forward * moveSpeed) * Time.deltaTime);
             }
        }
    }
}


function OnGUI(){
if (GunSlot == 1){      
 if (Weapon1 == 1){ 
  AmmoText = CurrentBullets + "/" + TotalBullets;
   if (GUI.Button (Rect (Screen.width/IconHorizontalPosition, Screen.height/IconverticalPosition, Screen.width/IconSize, Screen.height/IconSize), GunIcon, custom)){
    if (GunTotalBullets >= 17){
        if (GunCurrentBullets < 17){
        if (!GunReloadBoolean){
        StartCoroutine("ReloadGun");
        }
      }
    }
        else if (GunTotalBullets > 0){
        if (GunTotalBullets < 17){
        if (!GunReloadBoolean){
        StartCoroutine("ReloadGunLessMag");
        }
      }
    }
        TempMag = 0;
        GunMagazine = 17;
        }
GUI.Label (Rect (Screen.width/HorizontalPositionAmmo, Screen.height/verticalPositionAmmo, Screen.width/SizeAmmo, Screen.height/SizeAmmo), AmmoText, custom);
        for (var touch : Touch in Input.touches) {
         if (Input.touchCount > 0 && touch.phase == TouchPhase.Began && Time.time > nextFireTime) {
          if (GunCurrentBullets > 0){
           var hit : RaycastHit;
           var ray = Camera.main.ScreenPointToRay (touch.position);
            if (Physics.Raycast(ray,Mathf.Infinity,layerMask2)) {
             audio.PlayOneShot(Glock17ShotSound);
             nextFireTime = Time.time + ShotInterval1;
              if (Physics.Raycast (transform.position, transform.TransformDirection (Vector3.forward), hit, 1000, layerMask)) {
               var gunProjectile : Rigidbody = Instantiate(projectile, transform.position,   transform.rotation);
               gunProjectile.velocity = (hit.point - transform.position).normalized * 200;
               gunProjectile.transform.rotation = Quaternion.LookRotation(glock17Projectile.velocity);
               var otherObj : GameObject = hit.collider.gameObject;
                if ((otherObj.tag == "Zombie") || (otherObj.tag == "MediumZombie") || (otherObj.tag == "FastZombie")) {
                 var healthScript : ZombieHealth = otherObj.GetComponent("ZombieHealth");
                   if (healthScript.angle < 8.0){
                    var head = otherObj.transform.Find("Head");
                      Instantiate(bloodSplatter, head.position, Quaternion.LookRotation(hit.normal));
                      }
                      healthScript.HealthDamage(Damage);
                   }else{
            Instantiate(gunShotParticle, hit.point, Quaternion.LookRotation(hit.normal));
                }
            }
            GunCurrentBullets--;
            }
        }  
    }
    if (GunCurrentBullets < 1){
     if (GunTotalBullets >= 17){
      if (!Glock17ReloadBoolean){
       StartCoroutine("ReloadGlock17");
       TempMag = 0;
       GunMagazine = 17;
       }
   }
   else if (GunTotalBullets > 0){
    if (GunTotalBullets < 17){
      if (!GunReloadBoolean){
       StartCoroutine("ReloadGunLessMag");
       TempMag = 0;
       GunMagazine = 17;
                     }
                  }
               }
            }
         }
      }
   }
}
more ▼

asked Sep 11 '11 at 09:44 PM

FTheCloud gravatar image

FTheCloud
730 15 20 28

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

2 answers: sort voted first

Okay, "opening a door" is probably not a thing you can do from 20 ft away (so your first solution won't be nice anyway). It is something you want to do only when you are in front of a door and actually facing it.

So here is what you do (there is even a similar tutorial on unity3d.com if I remember right):

  1. on each update, do a ray cast with finite length (the length might be "2") torwards the character's viewing direction.
  2. if there is anything "no firey" hit by the ray, set a your "do not shoot" boolean to true. if there is no "no firey", set it false likewise
  3. when processing your input for shooting (either touches or gui), check for that boolean.
  4. be happy and move on with your awesome game :)
more ▼

answered Sep 11 '11 at 11:28 PM

japanitrat gravatar image

japanitrat
99 1 2 6

Using a raycast to detect if a certain object is in front of you poses an array of problems like: the player has to be SUPER close to the door or an enemy could get in the way of the raycast and if the player is facing the door and is in the minimal distance but they have an enemy by them and they want to shoot right then, they can't. Plus this is a 2D game I'm making so i don't need the player to be looking strait at the door, I just need it to be in the right amount of distance from the door. *** The problem with "opening the door form 20 ft away" had already been taken care of long before this question. I used Vector3.Distance() to determine the distance between the player and the door, which is more efficient then shooting raycasts in front of you. It also gives you some leeway so the player doesn't have to be face first on the door. The boolean wouldn't work for any gui, specifically the reload icon I mentioned, because both the gui and the fire script are called every frame. Unity can only tell everything that a boolean has been changed the frame after it switches and by then the bullets already been fired.

Thanks for the answer though.

Sep 12 '11 at 03:24 AM FTheCloud

humm, I did not see anything about a call of Vector3.Distance() .. furthermore, there is no need to be grumpy, i did not try to mock or offend you.

you also did not mention that a player also has to open doors that are behind him (a design thing) - otherwise you'll always have the problem of having enemies between the player and the door. The thing with the boolean in the calculation is, that the "is set the same frame" thing only happens once: the frame when the door enters to be in the hitzone. in every frame after this point, this boolean is still set in your component, thus it does not matter in which function you check for it's value.

Sep 12 '11 at 09:52 AM japanitrat

I said in my question that it was the basic script for shooting, not opening the door. The opening door from far away wasn't really part of the question to begin with. And i was just addressing your question, not trying to be grumpy. Sorry :( Again thanks for the answer.

Sep 12 '11 at 08:17 PM FTheCloud
(comments are locked)
10|3000 characters needed characters left

I don't see why ray casting isn't appropriate ? You need to make your touch handler work in layers...

Process all world touchables first, then process your non world touched messages next. Or if you do it the other way, check gui items first then world items.

I would first tag all items you want touchable as touchable. Then use gameobject.FindObjectsWith tag and transform all their bounding boxes to screen space. Loop through the bounding boxes and if one is touched, then handle the touch as you see fit: dispatched message, direct function call to a game manager, etc....

more ▼

answered Sep 12 '11 at 07:03 AM

Jeston gravatar image

Jeston
449 30 31 36

I'm already using layers with my raycast touch handler and all my layers are already tagged. I mentioned it in the second example script in my question. Booleans don't work in realtime when the gui and the touch.began are updated in the same frame, in the same script. I've tried what your saying and I mentioned it in the things I've tried in my question. It doesn't work. What I think I may need to do is use Rect.contains for my reload gui instead of OnGui itself.

Sep 12 '11 at 06:49 PM FTheCloud
(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:

x2399
x1554
x934
x93

asked: Sep 11 '11 at 09:44 PM

Seen: 1365 times

Last Updated: Sep 12 '11 at 08:43 PM