+1
Answered

Checking a variable against another always returning true?

GhostAegis 3 years ago updated by Lazlo Bonin (Lead Developer) 3 years ago 4

So, let me just preface by saying I'm loving Bolt so far. I'm an artist, not a dev, and it's been transformative in letting me put together gameplay systems entirely by myself.

That said, I'm having a bizarre problem, and I can't tell if it's due to a bug or something I'm doing wrong.

Basically, the situation is this: I have a controller macro that listens for input and sends out a custom event (to itself) with an argument based on the input it receives. The object that hosts this macro also has a variable to store the last "activated" gameobject. 

I then have a second object macro that listens to the controller object for the event, checks against the "activated" variable, and if the object's ID is equal to the current "activated" variable, is allowed to execute whatever code before updating the "activated" variable to the next object in the sequence. 

(Basically, I'm replicating the Unity EventManager system to create a navigable grid for gameplay/UI purposes, just simpler and more suited to what I want to do.)

Here's the problem. It only works once. The first time the event is triggered, the "activated" game object executes its macro correctly, and updates the "activated" game object variable on the controller to the next in the sequence.

For every single execution after that, EVERY SINGLE object with the object macro is reading the "activated" game object as being equal to its own ID variable during the "equals" check. This is in spite of the controller game object displaying the variable to clearly be equal to what it was set to on the first instance of the event trigger.

Then, because of this, nothing seems to be happening at all. The "activated" variable never changes again, but I don't get any errors either, despite all of the objects in the scene trying to push their "nextID" values to the "activated" variable every single time the event is called.

I've tried moving the system from a Custom Event to Update and triggering it by a time interval, I've tried moving the "activated" variable to another game object, to a scene variable, to an application variable. I've tried changing the variable types used for the check active system from a gameObject, to a string, to an int. It all ends up doing the same thing. 

I've included some screenshots below of a stripped-down version of the macros I used to reproduce the issue in a blank scene:

This is the "controller" macro. The clipped off stuff is just a bit designed to activate the event once per second for testing purposes.

Here's one of the objects.

Here's the other. They both use the same macro, embedded.


Note that the entire system looks like this regardless of when you check it. Both listening objects believe that the objectActive variable is equal to their selfID variables, every time the event triggers, without fail. But the objectActive variable sits at 1, unchanged. No errors, nothing.

I'm really at a loss here. What am I missing? Any help will be very much appreciated. 

For reference, this is a fresh project I set up just to use Bolt with not a week ago. I'm on Unity 2017.2.0f3. The only other things in the project are CineMachine, Unity Standard Assets, Probuilder Free, and Unity Post Processing (all from the asset store).

Bolt Version:
Unity Version:
Platform(s):
Scripting Backend:
.NET Version (API Compatibility Level):
GOOD, I'M SATISFIED
Satisfaction mark by GhostAegis 3 years ago
+2

The problem is that they are both listening to the event, and this is going to lead to a "stuck" state, regardless.   Bolt has to execute one of the listeners first (it can't do them both simultaneously.  If you able to step node-by-node, you would see that it would execute down one of the state graphs first, then the other (turns out it is the order they get enabled by, I'm pretty sure.)


Anyway, what ends up happening is, let's say Cube (1) is the one with the matching state, as in your example here.  It proudly (and correctly) detects that its ID matches the objectActive variable of the parent object.  Emboldened, it continues past the Branch node and Sets the objectActive variable on the parent to the nextRight value, which is 0.

Graph complete.  So, Bolt moves on to the other listeners of the event, to let them execute logic.  Cube now executes.  It looks at the objectActive variable of the parent, and sees that the value is a zero, matching its own ID.  Emboldened, it now passes the Branch node and sets its nextRight to 1.

To you, the user, they both pass and it appears incorrect, but they've done exactly what you told them to do.  Your first thought might be that if they executed in the opposite order all would be good, but no.  It would just switch which ID they got "stuck" at.


There are a couple of ways to handle this.  Probably the easiest is to pass the current objectActive as an argument in the Custom Event, and use that instead of the Get objectActive Variable node.  This will cause all of the nodes to get the same value argument regardless of execution order.  The Set Variable can remain the way it is, because only one of the nodes will get past the branch at that point.

Please forgive the lame attempts at humor, by the way.  Pulling an all-nighter for work, and I've had too much caffeine.

+2

THANK YOU!

Holy crap, this has been driving me crazy. That makes so much sense. I could not for the life of me tell what was happening (and it explains why when I hooked one of them up to an update instead of custom event it started working).

I can totally fix it now. Thank you again!