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. Voting for the Unity Awards are OPEN! We’re looking to celebrate creators across games, industry, film, and many more categories. Cast your vote now for all categories
    Dismiss Notice
  3. Dismiss Notice

OnTriggerStay Ignoring Certain Colliders

Discussion in 'Scripting' started by Supermoo48, Jan 4, 2018.

  1. Supermoo48

    Supermoo48

    Joined:
    Jan 3, 2018
    Posts:
    4
    Im making a game where the player needs to get into the car in a certain radius of it. I made the radius with a Trigger using OnTriggerStay. So when I’m in the trigger if I push E I get in the car. However if I push E when I’m not even close to the car it puts me in it, because the colliders in and around the car are activating it. So I’m trying for the OnTrigger Stay to only recognize the players colliders. Any ideas?
     
  2. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,292
    Check collider mask and compare it with a player collider mask.
    Or do a reference check.
    E.g.
    Code (CSharp):
    1. Player player = other.GetComponent<Player>();
    2. if (player != null) {
    3.     //... do your thing
    4. }
    Although I'd highly suggest you to avoid OnTriggerEnter/Exit/Stay methods as they're not realiable, and not always work. There's different methods to do proximity checks. E.g. you can use Physics.OverlapSphereNonAlloc to do the job done, and pass it only a Player LayerMask instead. This allows to realiably check an actual proximity and makes sure that the collider is only a player object.
     
    Supermoo48 likes this.
  3. DonLoquacious

    DonLoquacious

    Joined:
    Feb 24, 2013
    Posts:
    1,667
    You can change the Layer Collision Matrix to make it so that the only one object layer is capable of interacting with the car's trigger layer, and this could potentially stop all objects other than the player from triggering it.

    I would suggest that your logic here is actually backwards though- it appears you're determining whether the player can get into the car from the car's perspective, which is odd- it's the player's behaviour that should decide that. I would also recommend not putting Input commands in the Update functions of random objects in the scene, like cars- the player's behaviour should decide what inputs matter to the player's actions, and you should probably have an independent input manager to generate those input events, which the player and UI systems would be the primary subscribers to.

    Just some thoughts.
     
    ShadoX and Supermoo48 like this.
  4. Supermoo48

    Supermoo48

    Joined:
    Jan 3, 2018
    Posts:
    4

    Can you please send me an example of Physics.OverlapSphereNonAlloc. I don’t understand any Vector 3 things
     
  5. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,292
    Vector3 thing is just the center(position) of the sphere. Imagine placing it in a specific point in the scene. If something is inside of that sphere radius has same layer as passed layermask, it will be put inside passed Collider[] buffer.

    You can try using same method, but without the buffer, there's an example there.
    https://docs.unity3d.com/ScriptReference/Physics.OverlapSphere.html
    (Note that this will allocate memory for the Collider[] array)

    Anyway, in pseudo-code it would be something like this:

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3.  
    4. public class ProximityDetector : MonoBehaviour {
    5.    public Transform DetectionPoint;
    6.    public float DetectionRadius = 3;
    7.    public LayerMask DetectionLayer;
    8.    public int BufferSize = 16;
    9.  
    10.    private readonly Collider[] _hits;
    11.  
    12.    public ProximityDetector() { _hits = new Collider[BufferSize]; }
    13.  
    14.    private void FixedUpdate() {
    15.       int hits = Physics.OverlapSphereNonAlloc(DetectionPoint.position, DetectionRadius, _hits, DetectionLayer);
    16.       for (int i = 0; i < hits; i++) {
    17.          Collider otherCollider = _hits[i];
    18.  
    19.          Player player = otherCollider.GetComponent<Player>(); // Or GetComponentInParent<Whatever>()
    20.          if (player != null) {
    21.             // Allow to enter/exit whatever
    22.             break;
    23.          }
    24.       }
    25.    }
    26.  
    27.   private void OnDrawGizmos(){
    28.       if (DetectionPoint != null){
    29.           Gizmos.color = Color.cyan;
    30.           Gizmos.DrawWireSphere(DetectionPoint.position, DetectionRadius);
    31.       }
    32.   }
    33. }
    You can assign a transform in the inspector and drag it around to see how and where the sphere is.
    Note that this is can be improved further by adding a timer, or running a coroutine instead of doing this inside FixedUpdate to improve performance.