1
\$\begingroup\$

I have been trying to disable isTrigger in unity c# script on all GameObjects containing a certain tag. Currently my code works and disables the isTrigger part of the box collider, but it only does this for the first object with the tag I am looking for do this for all objects.

Here is the code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DefenseCollisionTrigger : MonoBehaviour {

    public static Rigidbody rb;
    public bool CanBePlaced;
    public GameObject[] defenseTriggers;

    void Start ()
    {
        CanBePlaced = true;
        defenseTriggers = GameObject.FindGameObjectsWithTag("Defense");
    }

    public void OnTriggerEnter (Collider other)
    {
        if (other.tag == "Defense")
        {
            CanBePlaced = false;
        } 
    }

    public void OnTriggerExit(Collider other)
    {
        if (other.tag == "Defense")
        {
            CanBePlaced = true;
        }
    }

    public void IsTriggerFalse()
    {
        foreach (Object dt in defenseTriggers)
        {
            Debug.Log("working on it");
            GetComponent<Collider>().isTrigger = false;
        }
    }
}

That is what is currently looks like. The public void IsTriggerFalse() is called on each time I go to instantiate an object with my mouse button. The Debug.Log is working and printing to the console. This is the closest I have came to making it work, but it only works for the first object. I have searched for hours and watched videos/looked at unity docs on foreach statements with no luck to my issue. I have also tried using foreach (GameObject dt in defenseTriggers) instead of just Object.

Anyone know how to solve my issue?

\$\endgroup\$

3 Answers 3

1
\$\begingroup\$

It's actually only working on the Object that's calling the code.

foreach (Object dt in defenseTriggers)
{
    Debug.Log("working on it");
    GetComponent<Collider>().isTrigger = false;
}

Is the same as:

foreach (Object dt in defenseTriggers)
{
    Debug.Log("working on it");
    this.GetComponent<Collider>().isTrigger = false;
}

Notice the this.. Meaning, for each object, you're getting the collider on the current object and setting it's isTrigger to false.

What you really want is something like this:

foreach (GameObject dt in defenseTriggers)
{
    Debug.Log("working on it");
    dt.GetComponent<Collider>().isTrigger = false;
}
\$\endgroup\$
8
  • \$\begingroup\$ It still works the same with any of that code being used. I have a basic scene with one cube in it, a floor, and my player. The cube is the only thing that has the isTrigger get disabled by this code. I am instantiating objects that follow my mouse, and then when I click it places them and then calls this IsTriggerFalse() code that we are looking at. It is all working except for the instantiated objects never get their trigger set to false. They have this script on the prefab as well and in scene when they are instantiated. I tried all the code changes you provided, but no luck yet. \$\endgroup\$ Commented Jul 31, 2017 at 18:27
  • 1
    \$\begingroup\$ And "working on it" gets printed to the log the correct number of times? What other debugging steps have you taken? How many times is this script in the scene? You've checked the tags on your objects? Do those objects exist when the Start() method is being called? \$\endgroup\$
    – House
    Commented Jul 31, 2017 at 18:29
  • \$\begingroup\$ Yes it gets printed every time it should be. It is currently only two different objects I am working with. One is a Cube called TriggerCube and the other is a instantiated prefab called WoodenFence(Clone). The fence one gets put on there multiple times correlating to how many fences I have placed in the scene, but none of the fence isTrigger ever get set to false. This script is only on my Empty GameObject that handles stuff in the background of the scene, a cube, and my instantited prefabs. the prefabs are not in the scene at the time of the Start (), but they do have this script attached. \$\endgroup\$ Commented Jul 31, 2017 at 18:31
  • 1
    \$\begingroup\$ If the objects aren't in the scene when the object holding this script calls Start() then the objects aren't going to be added to the list defenseTriggers. Attach the debugger and set a break point on the foreach (GameObject dt in defenseTriggers) line. See what's inside of defenseTriggers, where it's being called from and how many times it's being called. \$\endgroup\$
    – House
    Commented Jul 31, 2017 at 18:40
  • 1
    \$\begingroup\$ Why not just disable the collider on the object being placed, so it can't interact with existing/already placed objects? It sounds like you need some kind of GameManager with static methods for acting on all the objects so far. You shouldn't have each object trying to track all the other objects, it should be happening in one place only. Otherwise you get a mess like this. \$\endgroup\$
    – House
    Commented Jul 31, 2017 at 18:50
0
\$\begingroup\$

Well, I found the Answer. Not sure how good this is for performance or if it is advised against, but it is working for me!

I had to put the line

defenseTriggers = GameObject.FindGameObjectsWithTag("Defense");

into my IsTriggerFalse(); area so that it checks for the objects that were being instantiated. Thank you Byte56 for showing me that they weren't being recognized since they were not there at the time of the Start() call.

\$\endgroup\$
0
\$\begingroup\$

Well I think you forgot to reference the dt Object in core operation.

public void IsTriggerFalse() {
    foreach (Object dt in defenseTriggers) {
        Debug.Log("working on it");
        dt.GetComponent<Collider>().isTrigger = false;
    }
}
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .