This has to be a bug.
I’ve got a service running on a selector which periodically does a Sphere Overlap check to determine if any actors are in a certain range of the player.
I’m trying to set a Blackboard Key as Bool using the output of this overlap check, and it’s behaving erratically. So, to debug it, in the BT Service which sets the blackboard key, I’m also Print-Stringing the value of that bool just before setting it to a Blackboard key.
This is the result. I took these 3 screengrabs at random times during a single playtest.
The blackboard key seems to more or less do whatever the heck it wants to. Sometimes it lines up with the bool it’s being fed, sometimes it doesn’t.
Just for reference, here’s a screenshot of the relevant portion of the Service in question:
The string is being printed IMMEDIATELY before the Blackboard Key is being set, nothing is changing it. The Blackboard value itself isn’t set or even LOOKED AT anywhere else in the entire Behavior Tree (since it isn’t working); all it does is sit there in the “Simulating” screen, not getting set like it should.
Do me a favor: replace whatever child nodes of your selector you have with a simple “wait” node set for a brief interval (say 0.2) and see what happens… then do the same thing with the “wait” node set to a longer interval (say 5).
I’ve been trying to debug this and it SEEMS, at least on my end, that the problem is the way Blackboard values are set.
When a Service is running on a selector node, it performs the desired tasks at correct intervals, which manifests itself in correctly-printing strings. i.e. the tick fires off the “true” or “false” string exactly as it should.
BUT, the Service itself refuses to update blackboard values until it is between tasks. With a wait time of 0.2, the blackboard value is correctly written on my end; with a wait time of 5, the blackboard value only updates every 5 seconds.
The problem here is that if the service is trying to update a blackboard value that is relevant to child leaves/nodes/whatever, it cannot do this, since it must wait for those nodes to complete before it can change the value in question. It seems like a Service should be able to do what it does all the time while a selector/sequence is active (otherwise what’s the point?) but in fact it can’t change blackboard values except between tasks.
don’t have time to look at it now as the 4.4.3 has messed up my entire project. its a long time ago now but i did some sort of work around to get things running at the time. if i remember it was something like set the BlackBoard Values in the BTService and set the sevice interval to 0.1 and Random Deviation to 0.1 then add decorators to the Tasks and set them to abort self.
ill have a look when i get running again.
Hi Rhythmscript,
I am having a bit of trouble understanding exactly what you are trying to accomplish. I have a few questions:
- Does this occur on a blank project with no additional content?
- Is the value printing before or after the actual blackboard value change? It looks as though it is printing before the change occurred, If that is the case, in your images was the value true before the first image was taken (as in, recently changed to false and it continue to print true for a few moments)? If it is reading the print before the change that would at least clarify what may be occurring and make it easier to reproduce on my end. I’m also assuming you are calling this bool using an event tick?
If you have any additional information that could help us to reproduce this on our end please post it as well. Thank you and have a great day!
Ah man this behaviour tree is definitely experimental I’ve had so many problems with it today
RythmScript is correct. Here’s what mine is doing.
I have a service that runs that is supposed to update the blackboard with a float. Problem is it only updates once the child task finishes running. The logic of calculating the value is correct as I do a print screen after the value is set and the print screen is giving the value, the blackboard itself is at 0.00 until the task finishes when it then gets updated.
It’s easy to reproduce if you create a child task that never calls a ‘finish execution’ node, your service will never update the blackboard key.
Here’s some screenshots.
Just tried your workaround and yes that worked but I’ve decided I’m fed up of workarounds so this behaviour tree is unusable for me
Think I’m going to stop using this and UMG till it’s not experimental anymore. Have to do all this testing software stuff at work all week the last thing I could do with on a weekend is another day of bug fuelled confusion, could send a man insane
Yes, thank you, that’s exactly right. I was able to work around it by giving the selector multiple children (using a near-zero wait node with a conditional on it) to force the observer to call checks to the BB value which seems to cause it to refresh.
It seems as though services behave strangely on composites that have single children, likely because UE doesn’t “stay in” services with single children predictably…?
@AdamDavis Have you managed to reproduce this in house yet? If not do you need any assistance from me?
Just wondering as this has pretty killed me using the behaviour tree at the first attempt
guessing not
Think I’m gonna dump the behaviour tree, it doesn’t work.
I’m with you on that one pal, it waists so much of my time.
Hi everyone,
I am still looking into this, unfortunately it has been difficult to reproduce on my end. Does anyone have exact repro steps that would help in causing this to occur on my end? Thank you!
Hi : here’s how I do it.
First, create a blackboard key of an Actor type which you can use to store the player. Then, create a blackboard key of a boolean type which will act as a conditional.
Make the AI’s tree do this:
-
go to a selector which first checks for the player, and stores that player in a blackboard key. You can out a decorator on this which prevents it from firing once that key is set if you want; I did, it doesn’t seem to matter though.
-
that selector then goes to a second selector. The second selector has a service which ticks at some rate (mine was 0.2), and that service should be setting the bool blackboard key. Mine does a sphere overlap check and an array length from that to determine how many actors are within radius of the player, but it seems like any conditional will do, honestly.
-
that second selector has one child, which is a MoveTo task which moves the actor to the player. What should happen is that you use a Bool decorator here to either allow or prevent the MoveTo task from executing; this will behave oddly, and if you observe the BB values in real-time during PIE you’ll see them changing erratically and more or less completely independently of the output of the selector.
-
give the new selector a new first node (moving the MoveTo to the second child position), for example a very brief Wait node. If you give this child an opposite conditional check (i.e. The move executes if the Bool key is true, the wait executes if it’s false), then suddenly everything works! It’s like the selector isn’t “holding” the BT so the service isn’t running right, though if you stick a Print String inside that selector you’ll see that it IS running even though the BB value isn’t updating.
Did you try this simple reproduction?:
“It’s easy to reproduce if you create a child task that never calls a ‘finish execution’ node, your service will never update the blackboard key.”
It might be a bit more complicated than that I suppose I might be simplifying the issue. I’ll have a go creating a one branch behaviour tree when I get home with this conditions.
Hi savagebeasty,
I just saw that the finish execution node wasn’t hooked up. Do either of you have a section that doesn’t have a finish execution node at the end of a function. This includes if you have a branch that does nothing off of either true or false. One thing that is absolutely necessary in behavior trees is to have a finish execution on every single part of a function. If a branch does nothing off of a false value you must still include a finish execution or it will not register properly. See if that fixes this error for you.
Hi
Do you mean a finish execution in the service or the task? My tasks run a ‘finish execution’ node, I just meant if you take that node out from the task temporarily you can see the service never updates the value.
Surely even if the task is running but never finishes executing, the service should still be updating it’s values, isn’t that the point of services, to update values whilst lower branches/nodes are running or am I doing this all wrong?
I’ll be home in a couple of hours I’ll create a single branch tree and post the results.
I’m not sure what you mean by “I just saw the finish execution node wasn’t hooked up” Do you mean on my screenshots? That screenshot showing the blueprint for ‘GETDISTANCETONAVNODE’ is the service not one of the tasks if that helps
Right I’ve worked it out, looks like the value is getting physically updated but it doesn’t visually update in the behaviour tree therefore giving the impression that the blackboard value is not being updated when it actually is.
So basically the service does update the blackboard values as intended, it just doesn’t show it until the task is finished
Not sure if that’s the intended behaviour or not…
I probably didn’t explain myself very well which hasn’t helped, I also just realised I missed something very obvious in my initial testing…print the value of what the actual blackboard is, not just look at what the screen is telling me
So here’s some screenshots to explain the problem and an explanation of the service and task blueprints.
I’ve had to put it as a separate comment as I ran out of characters
Blackboard:
-Contains an int variable called ‘BlackboardInt’
Service:
-Has an int variable called ‘LocalInt’ that every service tick gets incremented by 1.
-Every service tick the blackboard variable ‘BlackboardInt’ is set to the value of ‘LocalInt’
-At the end of the tick it prints the ‘LocalInt’ and the ‘BlackboardInt’
Task:
-has an int variable called ‘TriggerLimit’ which is set to 100
-Every tick the ‘BlackboardInt’ is compared to the ‘TriggerLimit’, if the ‘BlackBoardInt’ is greater than the ‘TriggerLimit’ then the ‘Finish Execute’ node is called and returns ‘success’.
-Prints a string that tells us the task has completed.
In the screenshot ‘Behaviour Tree - value not set’ you can see that the Behaviour Tree blueprint is showing the ‘BlackboardInt’ value as ‘2’. I don’t know why it’s 2 that make no sense either to me I’d have thought it would be 0 or 1 but nevermind - either way it should be the same as the print log “Service Tick executed, Blackboard int is: 34” as that is printing the value directly from the blackboard with a ‘get blackboard value from int’ node. So the actual value in the blackboard is at 34 but shows in the blueprint editor window still at 2.
Screenshot ‘Behaviour Tree - value updated’ shows that the task has ran the ‘finish execute’ node and now the behaviour tree visually shows the correct value.