GetWorldTimerManager in derived class which is not in UWorld

Unless I’m severely mistaken, you don’t actually have an instance of “AMeleeCombatSystem”. I’m not even sure how this compiles, as “meleeSystem” seems to be a local variable in your constructor.

I would suggest the following:

In your Player’s Header:

UPROPERTY()
AMeleeCombatSystem* MeleeCombatSystem

In your Player’s cpp:

ABaseCharacter::ABaseCharacter() 
 {
// Can't spawn actors in constructor
 }

ABaseCharacter::BeginPlay()
{
    Super::BeginPlay();

    // Spawn melee system
    MeleeCombatSystem = GetWorld()->SpawnActor<AMeleeCombatSystem>(AMeleeCombatSystem::StaticClass);
}

Now after this, you should have a proper instance of AMeleeCombatSystem which would have access to all the Actor goodies.

Also, AMeleeCombatSystem::SomeFunction() would imply that you’re calling a static method on that class, which I don’t think is the case here.

Hi,

I have a setup where I have a ABaseCharacter which has several abilities, like talking to NPC, target enemies and so on. Yesterday I decided to make my MeleeCombatSystem more modular to reuse it in other projects.

Basically I did something like that:

ABaseCharacter::ABaseCharacter() 
{

}

void ABaseCharacter::startMelee() 
{
     // do stuff do stuff do stuff
    doSomethingWithTimerInMeleeCombat();
}

void ABaseCharacter::doSomethingWithTimerInMeleeCombat() 
{
    GetWorldTimerManager()-> // and so on
}

This works well, no issues. When I decided to make it more “modular” I changed my code to following

ABaseCharacter.h

// forward declaration 
class AMeleeCombatSystem;

class AMeleeCombatSystem : ABaseCharacter
{
AMeleeCombatSystem* meleeSystem;
}

ABaseCharacter.cpp

#include “Combat/MeleeCombatSystem.h”

ABaseCharacter::ABaseCharacter() 
{
   AMeleeCombatSystem *meleeSystem  = Cast<AMeleeCombatSystem>(AMeleeCombatSystem::StaticClass()->GetDefaultObject();
}

void ABaseCharacter::startMelee() 
{
    if(meleeSystem) 
    {
        meleeSystem->doSomethingWithTimerInMeleeCombat();
    }
}

/*** Inherit from baseCharacter in header file ***/
AMeleeCombatSystem : ABaseCharacter

In AMeleeCombatSystem.cpp

void AMeleeCombatSystem::doSomethingWithTimerInMeleeCombat()
{
      // do stuff do stuff do stuff
      GetWorldTimerManager()-> // CRASHED
}

I believe the issue is that this MeleeCombatSystem is not really in the UWorld* and just invoked by using AMeleeCombatSystem *meleeSystem = Cast(AMeleeCombatSystem::StaticClass()->GetDefaultObject();

So I tried to change it to the following

void AMeleeCombatSystem::doSomethingWithTimerInMeleeCombat()
{
      // do stuff do stuff do stuff
      ABaseCharacter::GetWorldTimerManager()-> // CRASHED also
}

Did someone ran into similar problems or am I looking in the wrong direction?
I am looking for a way to use GetWorldTimerManager() for this class which is not placed in the UWorld.

Thanks in advance

Thanks for you answer.
For some other modules I did it the same way like handling npc interaction and so on. I can access the class AMeleeCombatSystem and call every methods, which does not include GetWorldTimerManager();

I forgot to mention that AMeleeCombatSystem is derived from ABaseCharacter and that meleeCombatSystem is declared in my header file,I will update this.
I will try the UPROPERTY() in my header file definitly, but why does this help that GetWorldTimerManager() does not crash my engine?
I just try to understand :slight_smile:

I have the baseCharacter placed in the world, but not the MeleeTargetSystem.
So basically why should I prevent this actor from beeing garbage collected when it isn’t in the UWorld? Would this help in this case?

That why I tried ABaseCharacter::GetWorldTimerManager() because the base character is in the UWorld

I also tried GetWorld()->GetWorldTimerManager(); without success :confused:

I’m not on my UE pc but will give it a try later on :slight_smile:

Yes, UPROPERTY() prevents the Garbage Collector from destroying Actors. You will definitely run into problems if you don’t decorate your actor pointer declarations with it.

I think you could also try the following instead:

GetWorld()->GetWorldTimerManager()

No I don’t think so - Garbage Collection only applies to instances as far as I know.

Have you tried my suggestion of actually Spawning and instance of AMeleeCombatSystem?

edit:
Also see this post

I’m not sure exactly what GetDefaultObject() does but I suspect the problem comes from not calling GetWorldTimerManager() on a “proper” Actor instance.

Yes you are right something seems to be wrong with my instance, but beside that function which has a direct connection to UWorld everything else works.

Unfortunately I cannot try until I’m at home :slight_smile:
But if possible I want to avoid spawning an instance of MeleeTargetSystem because from mind point of view it should not be necessary in my implementation to spawn some kind of helper module
I will let you know the results if I was able to test this.
Thanks so far for your time and ideas:)

Hi Staticvoidlol,

I solved this by using one of your hints.
I did not derived this CombatSystem from my base character, since its better to have this independent. So I derived it from an actor directly and placed it into the UWorld.
Now I dont have any issue with the timer manager and a more loosely coupled module