Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question checking raycast if it is obstructed by another object before a box collider.

Discussion in 'AR' started by nosarious, Jun 9, 2023.

  1. nosarious

    nosarious

    Joined:
    May 14, 2014
    Posts:
    16
    I have a scene in Ar which has several objects that have been tagged 'object-1', etc. They all have box colliders to allow interaction. They are inside an abject (a building) which can be scaled, but I am having accidental activations when a user inadvertently taps an object 'through' another object (ie, there is something in the way that should obstruct a tap, like an outside wall or other piece of furniture inside the building)

    I am using a script to check a raycast to see if these objects are 'tapped' by a person using the AR app on a mobile device.

    Right now, though, if the box collider is hit by a raycast then it activates (and plays an audio file or movie)

    Is there a way to validate a raycast? I tried to search for the term 'visible to the camera' but this doesn't really help as any object in a field of view is 'visible to the camera' ...

    I have an image that should help describe the problem. The tap should not work if it happens on the shelf, but should work if it is on the visible part of the suitcases.



    This code relies on two other scripts (uneeded) that start specific audio or video files. I'm interested in checking if the touch on an object is obstructed by something else visually.


    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEngine.XR.ARFoundation;
    6. public class playSourceFromClick : MonoBehaviour
    7. {
    8.  
    9.     private Vector2 touchPosition = default;
    10.  
    11.     Camera m_MainCamera;
    12.  
    13.     public bool isMediaPlaying;
    14.  
    15.     MediaController mediaScript;
    16.  
    17.     AudioController audioScript;
    18.  
    19.     void Awake(){
    20.         mediaScript = GameObject.FindGameObjectWithTag("mediaTag").GetComponent<MediaController>();
    21.         audioScript = GameObject.FindGameObjectWithTag("audioTag").GetComponent<AudioController>();
    22.     }
    23.    
    24.     private void Start()
    25.     {
    26.         m_MainCamera = Camera.main;
    27.         isMediaPlaying = false;
    28.  
    29.         Debug.Log ("media "+mediaScript);
    30.         Debug.Log ("audio "+audioScript);
    31.     }
    32.  
    33.  
    34.     void Update()
    35.     {
    36.         //Debug.Log("isMediaPLaying "+ isMediaPlaying);
    37.         if(Input.touchCount > 0 && !isMediaPlaying)
    38.         {
    39.             Touch touch = Input.GetTouch(0);
    40.             touchPosition = touch.position;
    41.    
    42.                 if (touch.phase == TouchPhase.Began)
    43.                 {
    44.                     Ray ray = m_MainCamera.ScreenPointToRay(touchPosition);
    45.                     RaycastHit hitObject;
    46.  
    47.                     //Debug.Log(touchPosition);
    48.                     //Debug.DrawRay (ray.origin, ray.direction * 100, Color.yellow);
    49.                    
    50.                     if (Physics.Raycast(ray, out hitObject))
    51.                     {
    52.                        
    53.                          //if(hitObject.collider != null){
    54.                             //Debug.Log(this.gameObject.name + " was tapped ");
    55.                             //Debug.Log("in main click tapcheck is currently "+isMediaPlaying);
    56.                             //did user tap the object
    57.                             if(hitObject.transform.CompareTag("object-1"))
    58.                             {
    59.                                 //play audio-file-2
    60.                                 //Debug.Log("tapped newspapers");
    61.                                 audioScript.playTrack0();
    62.                             }
    63.                      }
    64.                   }
    65.                 }
    66.           }
    67.      }
    68. }
    69.  
     
  2. tduriga

    tduriga

    Joined:
    Dec 9, 2015
    Posts:
    52
    Do I assume correctly that you have some collider on the shelf model? Maybe you could try something like this:

    Code (csharp):
    1.  
    2.         Ray ray = m_MainCamera.ScreenPointToRay(touchPosition);
    3.         RaycastHit[] hit = new RaycastHit[10];
    4.         hits = Physics.RaycastNonAlloc(ray, hit, 100);
    5.         if (hits > 0)
    6.         {
    7.             RaycastHit closestHit = hit[0];
    8.             for (int i = 0; i < hits; i++)
    9.             {
    10.                 if (hit[i].transform != null)
    11.                      if (hit[i].distance < closestHit.distance) closestHit = hit[i];
    12.             }
    13. //check for closestHit tag, name, layer, etc. here
    14.  
    15.         }
    16.  
     
  3. zulo3d

    zulo3d

    Joined:
    Feb 18, 2023
    Posts:
    510
    It seems like you're new and you don't understand how the raycast function works. The raycast will be blocked by other objects that have colliders on them. So it won't hit/touch the suitcases if you place a collider on the shelf.
     
  4. nosarious

    nosarious

    Joined:
    May 14, 2014
    Posts:
    16
    Thank you for the insight into how colliders can be used to judge the way an object is or isn't touched based on what is in front. We have been trying to find ways to avoid people accidentally starting audio while initially placing, moving and scaling the building itself. I shall have to have box colliders around every wall as well (it can get tricky but will be int he best interest of this project)

     
  5. nosarious

    nosarious

    Joined:
    May 14, 2014
    Posts:
    16
    Sorry I didn't respond earlier. I had to check your suggestion versus tduriga. An experiment shows that indeed a box collider will interrupt a raycast and prevent it from 'spearing' through to the other object. Most of the objects don't have colliders on them so I shall have to add them to the larger ones I need to behave as 'blocks' for objects.

    the walls of the building will be difficult as they are integrated into the model, so not separate elements. It may not behave properly if I use the mesh collider since it is a fairly complex model.

    Thanks again.

     
  6. zulo3d

    zulo3d

    Joined:
    Feb 18, 2023
    Posts:
    510
    A mesh collider will be fine for such a simple scene. Especially considering you're only doing a raycast when the user touches the screen.