Download

Help With Order Of Operation (cannot make sense of it): Reference To C++ BatteryCollector Tutorial

Hello Unreal-ites HAPPY NEW YEAR!!! Thank you for clicking on this post.

I will try to keep this as short as possible.

In C++ BatteryCollector Tutorial https://www.youtube.com/watch?v=1tqT…dGiM4&index=12

In BatteryCollectorCharacter.cpp , a function called ColectPickups() is implemented. The order of operation in the for loop:

  1. Test overlapped actors as type APickup. If true then
  2. Run Func TestPickup->WasCollected() <- if this is a type of ABatteryPickup (which they are in the video), the override found in ABatteryPickup.cpp has an instruction Destroy()
  3. Test if the item picked up is a type of ABatteryPickup, if true
  4. Add the ABatteryPickup.BatteryPower to an accumulator.
  5. Set the ABatteryPickup.bIsActive = false
  6. After the loop, update the character’s total power with that of the the accumulator

At the end of the posted video, Character’s CurrentPower attribute updatesr.

On my end, as it should, the program crashes because the line: if(BatteryTest) should cause some kind of exception accessing a null ptr. Why? ABatteryPickup instances are destroyed BEFORE number 3 in the order of ops. If I comment out the line Destroy() in the function ABatteryPickup::WasCollected , it works correctly.

Furthermore, if i change the line from if(BatteryTest) to if(IsValid(BatteryTest)) the program continues to run, batteries disappear because they are destroyed, but the character’s power does not change.

if I perform the test: if(!IsValid(TestBattery)) this enters showing that the pointer is no longer valid AND/OR it has a PendingKill() true.

Please help me understand if I am doing something wrong, or, the video is just lucky somehow with what appears to be a race condition (perhaps the Destroy() carry out is deffered until after the frame in the 4.9 version, where in, at least, 4.22, the work is done right there, or perhaps there are arguments that were implied in 4.9, where I need to be explicit in 4.22 to match the behavior? Can someone explain how the code in that video actually works without crashing the editor like it should? It feels like a lucky race condition, no?

I will be happy to post any code you wish.

-Erol

Could you post the code you have?

It is weird that


if(BatteryTest)

crashes since it has already been tested earlier for being valid and not pending kill. Perhaps you are initializing the pointer to a random piece of memory?

BatteryCollector_SourceAsOfEndOfVideo13.zip

Hey @GarnerP57 ,

Thank you for responding. Happy New Year (if you celebrated New Year last evening)!!

Believe it or not, I noticed that failure in the video and just used if(IsValid(ptr)) instead of using the author’s code, because, the line before it (the function WasCollected), if it’s a battery, has the Destroy() instruction, so the ptr would be invalid by the time it got there, which yes, does crash the editor. So the pickup disappears and the Character’s power level never updates. Then I went back and troubleshooted and found where the issues is, then thought, wait, how is the author’s code running correctly (updating power AND not crashing)?

Attached is a zip file containing all of my source as of Video 13. My naming conventions are slightly different from the author’s so some function names and variable names are not the same.

Please let me know if you have ANY questions at all, or want more information. I can’t see if my zip file actually came with this post. So let me know if it didn’t.

-Erol

Hey @GarnerP57 , were you able to take a look at the source code and see if you could arrive at an answer to my question?

-Erol

The tutorial is a bit odd to be honest. You should not call any functions on the Actor itself after Destroy has been called.

Hey @GarnerP57 , I don’t think that statement is invalid in any way. But, could you provide some insight on just how that tutorial is working the way it is? Do you think it was something that may have worked so long ago but now has changed (maybe someone reported that capability as a bug long ago?). Just so strange.