3

I have a safe zone with colliders detecting if my player is inside or not by sending an event message. But there are a lot of other objects inside the safe zone.

To detect if my player is inside, I use:

void Start()
{
    if (player == null)
    {
        player = GameObject.Find("Gringan").GetComponent<Player>();
        Debug.Log("player = " + player.name);
    }
}

void OnTriggerEnter(Collider other)
{
    //else ...
    if (other.transform.parent.GetComponent<Player>() == player)
    {
        print("Collision detected with trigger object " + player.name);
        safe = true;
        m_Player.PlayerIsSafe.Send(safe);
    }
}

For others objects inside the safe zone, I get a null reference exception. (other objects don't need .parent and don't have a Player component...)

I would like to avoid that by detecting these items too without getting error messages. I would like to write something before the "//else" to only have my player in the next statement (if). I tried with tags and many several ways but can't get them to work.

Serlite
  • 12,130
  • 5
  • 38
  • 49
mad_mask
  • 776
  • 2
  • 10
  • 31

1 Answers1

3

A common solution here is to use tags to identify your objects, so you know what they are before you attempt a GetComponent() on them. This saves you processing time and avoids errors you might get trying to use non-existent components.

For example, if you tag the top-level GameObject in your player object hierarchy with the tag "Player", you could write:

void OnTriggerEnter(Collider other)
{
    //else ...
    if (other.transform.root.CompareTag("Player")
        && other.transform.parent.GetComponent<Player>() == player)
    {
        print("Collision detected with trigger object " + player.name);
        safe = true;
        m_Player.PlayerIsSafe.Send(safe);
    }
}

Note: Thanks to short-circuiting with conditional operators in C#, you don't need to write multiple nested statements for the comparisons - if the CompareTag() fails, the subsequent GetComponent() won't be executed.

Hope this helps! Let me know if you have any questions.

Serlite
  • 12,130
  • 5
  • 38
  • 49
  • Thanks for your reply and your explication. I tryed but i have error : The others objects in safe zone dont accept : ".parent" but i need it for detecting my player. NullReferenceException: Object reference not set to an instance of an object SafeZone.OnTriggerEnter (UnityEngine.Collider other) (at Assets/My Assets/Scripts/SafeZone.cs:60) – mad_mask Jan 25 '17 at 15:23
  • @mad_mask Hmm, can you add an image of the scene hierarchy of your player object into your question? It'd give a clearer picture to me of how you've set things up. (Largely, I'm wondering why you've placed your collider underneath your `Player` component, rather than on the same level.) – Serlite Jan 25 '17 at 15:38
  • @mad_mask Edited my answer based on an assumption, let me know if it works for you. – Serlite Jan 25 '17 at 15:48
  • https://s28.postimg.org/ky8lfzzql/trigger.png https://postimg.org/image/5pio28621/ – mad_mask Jan 25 '17 at 15:53
  • @mad_mask Thanks - I think my edit should work alright, then - just place the tag on the top-level GameObject in your player object hierarchy (Gringan, I guess?), and it should detect it without problems. – Serlite Jan 25 '17 at 15:56
  • @mad_mask That's good, note that the key part of my edit is turning `other.transform.parent` into `other.transform.root`, which should end up checking the Gringan object in the player object (and checking the top-level transform in any other objects, without null reference exceptions). – Serlite Jan 25 '17 at 16:00
  • Sorry didnt saw your edit. It work very well. Thank you very much for your time and your answer. – mad_mask Jan 25 '17 at 16:02