- Home /
Variable is always being returned as false even while set to true
pathwayChecker[] walls;
walls = spawnedRoom.transform.GetComponentsInChildren<pathwayChecker>();
for (int i = 0; i < walls.Length; i++)
{
if (walls[i].deadendFound == true)
{
print("WORKING BLOCKED");
}
if (walls[i].doorwayFound == true)
{
print("WORKING OPEN");
}
}
So in this code, I am attempting to pull some variables from another script which successfully detects whether the opening check gameobject is colling with an "opening" tag trigger or a "wall" tag trigger. While going through the function of spawning the rooms, these variables do properly change when they detect a doorway (opening) or a deadend (wall). Below are two different nodes that adjusted properly when the room they were attached to was instantiated.
However, when I attempt to reference those variables in the code at the top, the variables are always returned as false. I'm not quite sure what's causing it, since the variables should be updating the instant the room spawns with their OnTriggerEnter function.
Thanks for any help in advance, and let me know if any more information is needed!
For the sake of testing, are all cases being covered thoroughly? As an example, does everything look right with a little more diagnostic info?
walls = spawnedRoom.transform.GetComponentsInChildren<pathwayChecker>();
Debug.Log(string.Format("walls populated: {0}", walls.Length));
for (int i = 0; i < walls.Length; i++)
{
Debug.Log(string.Format("deadend: {0} --- doorway: {1}", walls[i].deadendFound, walls[i].doorwayFound));
}
Alright, I added your debugging code and looks like it's working properly. The walls array fills accordingly based on the number of openings, but for conciseness I only screenshot the info for the first room spawned.
As you can see, there's two openings here. One that should be set to false (no room has spawned there yet, so false to both deadend AND doorway) and one that should have deadend set to true. Is it possible that the OnTriggerEnter function is somehow being called after the variables are being checked?
Wait, I clearly overlooked an important detail in your original question:
What is the context in which OnTriggerEnter() should be called when the room is generated? Are you spawning a Trigger-flagged Collider on top of a generic Rigidbody or is there some other specific activation method you're using?
If you're just looking to run a function when the rooms are created, can you not just use Awake() or Start() instead?
As an additional verification step, you could try adding diagnostic info to your "pathwayChecker" scripts to see if they're being called in the first place:
// in "pathwayChecker"
// Whichever function is setting the values
void OnTriggerEnter(Collider other)
{
// After setting values, print out the result
Debug.Log(string.Format("pathwayChecker: {0}: deadend: {1} --- doorway: {2}", gameObject.name, deadend, doorway));
}
Then, you can compare the log outputs and see whether they're being processed in the order you're expecting.
Answer by Eno-Khaon · Aug 01, 2021 at 03:31 AM
Well, there's still one piece of information missing, but I think I've got the whole picture here anyway, now.
So, let's go back to your original script excerpt.
Since you're seeing the segments correctly in the inspector, I'm guessing there's not any real delay between when you're generating the rooms (e.g. Instantiate()) and when you're comparing them to see whether they're *already* determined to be adjacent to other parts (i.e. "deadend" and "doorway" flags). I assume you're instantiating the pieces, then checking the connections between them on the same frame.
Why would this be a problem?
OnTriggerEnter() is handled by the physics system, which wouldn't be processed as the pieces are being generated. In fact, there's no guarantee that physics would be processed simply before the second frame; you would need to delay verifying connections by an indeterminate amount. Still far less than the time it would take to interact with them in almost any circumstance, but a delay nevertheless.
The key problem here is that to deal with this, you either have to delay checking the rooms, or re-evaluate how you're actually checking the neighboring rooms using a more immediate means.
The delayed option would involve using a Coroutine to stall until after a physics update is guaranteed to have taken place first and allowed OnTriggerEnter() to be processed:
void Start()
{
StartCoroutine(BuildRoomBorders);
}
IEnumerator BuildRoomBorders()
{
pathwayChecker[] walls;
// ...
for (int i = 0; i < walls.Length; i++)
{
// etc.
}
}
Re-evaluating your approach to still function on the same frame (which, for one thing, is more sensible), can most likely be done using Physics.OverlapBox() rather than relying on OnTriggerEnter() when it gets around to it.
This would mean changing your instantiation scheme to immediately perform the checks for neighboring pieces:
// Simple example, since I don't know what you already have
for([some loop])
{
Instantiate([room parts]);
}
// Have data gathered for here, reusing a bit
for(int i = 0; i < walls.Length; i++)
{
Collider[] collidersInRange = Physics.OverlapBox([intended side of room]center, halfExtents, orientation);
// Other options include OverlapBox() for the entire size of room, then checking direction between room segments
// or, still utilizing direction, Physics.Raycast() to check for adjacent objects
for(int j = 0; j < collidersInRange.Length; j++
{
if(collidersInRange[j].CompareTag("Deadend"))
// etc.
}
}
Thank you for the assistance! I'll get to work on implementing the new process tomorrow morning. I had a feeling that the issue had to due with the time it was taking for the engine to actually realize it was colliding with something else.
EDIT: Just implemented it. The overlapbox works perfectly, I added it under the start() function. Thank you for the help!
Your answer
