Note: This bug was original posted in the UT forum. I was asked to report it in the engine forum (forwarding me here). I mostly kept the structure from that post and added repro steps.
AND and OR nodes in Blueprint behave differently to how C++ (or other common [script] language) works.
Example code:
C++
AController* Controller = NULL;
// if (Controller && Controller->PlayerState)
if (Controller != NULL && Controller->PlayerState != NULL)
{
// DO SOMETHING
}
This is a valid if-condition (PlayerState won’t be accessed; no crash).
UnrealScript
local Controller C;
C = none;
if (Controller != none && Controller.PlayerState != none)
{
// DO SOMETHING
}
Similar to C++. No “accessed none” log (no crash).
Blueprint equivalent
This casues an error like this:
The log will contain an entry like this: LogScript:Warning: Accessed None 'NewVar_0' Untitled_C /Temp/UEDPIE_0_Untitled_3.Untitled_3:PersistentLevel.Untitled_C_0 Function /Temp/Untitled_3.Untitled_C:ExecuteUbergraph_Untitled:0074 PIE:Error: Error Accessed None 'NewVar_0' from node Branch in graph 'EventGraph' in blueprint Untitled
The Blueprint is trying to access the class field PlayerState of “NewVar_0” because it would process something like this (in C++):
AController* Controller = NULL;
bool b1 = Controller != NULL;
bool b2 = Controller->PlayerState != NULL;
if (b1 && b2)
{
// DO SOMETHING
}
Controller->PlayerState
would result into a crash (null pointer) which is catched by the Blueprint VM and reported as an error. The and boolean node is using UKismetMathLibrary::BooleanAND(bool, bool)
which takes two evaluated boolean values. This is likely the source of the problem.
The OR node behaves the same.
if (Controller != NULL || GetController(Controller)) // GetController(ByRef)
{
// DO SOMETHING
}
GetController would only be called if the Controller variable is not already set.
For Blueprint test, I created two pure functions which both calling a unique message and return true.
Log:
LogBlueprintUserMessages: Func1 called. LogBlueprintUserMessages: Func2 called.
Func2 is also processed even if there is no need for it. In C++ it would only process Func1 as it already returns true (true || ? == true).
A workaround for the AND node would be using separate Branch nodes sequentially. This is not ideal for more than 2 expressions (and you have to process/link each false case).
Original post in the UT forum:
[AND and OR nodes’ connections are always evaluated (no associativity)][5]
Additional reference:
[MSDN: Logical AND Operator: &&][6]
[MSDN: Logical OR Operator: ||][7]
Editor version:
4.8.0-2710036+++depot+UE4-UT-Releases
UT Editor Build 2710036 (10/01/2015)
Detailed description of the issue:
The associativity of the Blueprint nodes AND, OR, … are not the same like these from C++ (and other common languages). Each connected statement/node will be evaluated.
Repro Steps:
- Create a new level (File > New level)
- Open the level blueprint editor (Toolbar Blueprints > Open Level Blueprint)
- Create a variable of type Controller (My Blueprint > Add New > Variable)
- Add an Event Begin Play node to the EventGraph (or use the existing greyed-out one)
- Connect the above to a Branch node
- Drag from the Condition and create a AND boolean node.
- Drag and drop the new variable (NewVar_0) from the My Blueprint tab into the EventGraph
- Drag from that variable and create a Is Valid node
- Connect this node to the A pin of the branch node.
- Drag another time from the variable and create a Get Player State node
- Drag from that player state node and create another IsValid node
- Connect that 2nd Is Valid node to the B pin of the branch node
- Choose to play that level
- Exit the Play In Editor session (Escape) and open the output log (Window > Developer Tools > Output log
The Level Blueprint should looks like this:
The log will contain an entry like this:
LogScript:Warning: Accessed None 'NewVar_0' Untitled_C /Temp/UEDPIE_0_Untitled_3.Untitled_3:PersistentLevel.Untitled_C_0 Function /Temp/Untitled_3.Untitled_C:ExecuteUbergraph_Untitled:0074 PIE:Error: Error Accessed None 'NewVar_0' from node Branch in graph 'EventGraph' in blueprint Untitled