Inherited coroutine not working as I expected

This coroutine works fine but when I use a base class version of it…

it does not work. The pawn stays perpetually null. Why is this the case?

1 Like

Let me know if I was not clear enough

I’m interested about this as well. Can anyone shed some light on this?

@GreatGuru is on the case.

1 Like

Ok so I am not sure what exactly you are trying to accomplish but I assume you want to wait until the data member @pawn is set to something non-null.

I further assume what you are doing is in spirit the following:

some_obj.@pawn : Pawn!null
some_obj.@pawn : some_pawn

And you expect some_obj.@pawn._wait_not_null to exit after that last statement, when @pawn becomes non-null, but it won’t.

It doesn’t because some_obj.@pawn is rebound to a new object some_pawn while some_obj.@pawn._wait_not_null keeps running forever in the object previously contained in some_obj.@pawn which is null (and will stay forever so).

Confused? The tricky concept here is that an Entity object in SkookumScript is really just a reference to a UE4 UObject, so multiple Entity objects in SkookumScript can refer to the same UE4 UObject, or it can be null, meaning it refers to no UObject at all. So there are two levels of reference going on here:

  1. The data member @pawn which refers to a SkookumScript Object (here of type Entity)
  2. The SkookumScript Object of type Entity which in turn refers to a UE4 UObject

To fix this situation, the rebinding operator : needs to be changed to an assignment operator :=. The data member @pawn keeps then referring to the same SkookumScript Object, the one which _wait_not_null is testing.

some_obj.@pawn : Pawn!null
some_obj.@pawn := some_pawn

Now _wait_not_null will correctly exit when @pawn is reassigned.

Let me know if this fixes your issue!

1 Like

I don’t do the assignment at all. @pawn is located in the PlayerController class, it is assigned through the Unreal Engine, not me.
Here are some more explicit pics:

This works:

This does not:

I assumed that it should work in this case because the code is doing the same thing, asking if that reference is done being null. Unless the inline loop version is actually getting some updated reference that the method call version is not acquiring. To me, that seems quite confusing. What you wrote above makes perfect sense, the coroutine is running on some other object, but in the code I created I thought it would be running on the same object since I am not explicitly doing a rebind myself(Unreal is instantiating it somewhere).

Ah ok. So due to the way that raw data members work the coroutine _wait_not_null will always run on a copy of the data member made at the moment the coroutine is invoked. For this to work as expected you have to read the data member @pawn each iteration in the coroutine, for example by creating a coroutine PlayerControllerSpecial@_wait_until_pawn_not_null. I admit this is a bit unintuitive at the first glance.

1 Like

Ah, that is what I get for not reading the documentation, but guys never read instructions, right? I see now, thank you!

1 Like