class FKServerManager : public TSharedFromThis<FKServerManager>
{
public:
/** constructor. */
FKServerManager(TWeakObjectPtr<UKLocalPlayer> InLocalPlayer);
/** destructor. */
~FKServerManager();
/**
* @return the global instance of the FKServerManager.
*/
static TSharedPtr<FKServerManager> Get()
{
return FKServerManager::Instance;
}
/**
* @brief Initializes the server manager with a local player.
*
* @param InLocalPlayer The local player.
*/
static void Initialize(TWeakObjectPtr<UKLocalPlayer> InLocalPlayer)
{
if (FKServerManager::Instance.IsValid())
{
FKServerManager::Instance.Reset();
}
FKServerManager::Instance = MakeShareable(new FKServerManager(InLocalPlayer));
};
This class is in charge of searching servers and game instance running on servers.
The LocalPlayer implements a ULocalPlayer
UCLASS(config=Engine)
class UKLocalPlayer : public ULocalPlayer, public FKILocalPlayer
{
GENERATED_UCLASS_BODY()
public:
/**
* Get the world the players actor belongs to
*
* @return Returns the world of the ULocalPlayer.
*/
virtual UWorld* GetWorld() const override
{
return ULocalPlayer::GetWorld();
};
/** Quick access to the world timer manager */
FTimerManager& GetWorldTimerManager() const
{
return GetWorld()->GetTimerManager();
}
....
When I launch a search of servers, I need to call a function in the Server Manager to reinitiate a search in case no adequate games are found.
To do it I made the following call within a function in the Server Manager.
Is the problem related to the fact that the call is made within a function in a result of Session Search Completed ?
Or is it a problem with a thread safe compatibility ?
I don’t want to call the function LaunchSearchAgain() within the Session Search Completed function to avoid accumulating function calls in the stack.
Anyone has an idea why the function is never called ?
I think the problem that you are running into here is that the SetTimer template is not working when you try to call a function outside of the class it is being used in. You can get around this by implementing a function in the class where you are setting the timer that will call the function in the other class that you need.
I tried this by setting up a dynamic delegate in my class that had the timer, and bound the delegate in another class. When the timer ran out, it called a function in the same class that broadcast the delegate, which was picked up by the other class that then ran its own function. You could conceivably have the delegate broadcast immediately and the timer run in the other class before calling its own function, or you could even have a timer run in both classes before and after the delegate is broadcast.
You mean that the call-back must be in LocalPlayer in my case ?
Since the timer is set within the FKServerManager and the call-back function is in FKServerManager also.
I have to use the LocalPlayer to get a valid World object to access a valid TimerManager.
Sorry, I didn’t notice that your timer was being set in the FKServerManager class. Would it be possible to get a sample project showing how you have this set up?
Sorry, I thought I had replied to your comment on Friday. I think all that I would need is any class involved in this setup. In particular, FKServerManager, UKLocalPlayer, and FKILocalPlayer. I think that will provide me with enough information to see how you are setting this up and, hopefully, why the function is not being called.
Thank you for providing the sample code. I believe I was able to see what you described, but can you confirm that this only happens when trying to quit from one of the maps in the project when playing in Standalone mode?
When I tried quitting from the Main Menu, or when running the game in the Visual Studio debugger, it appeared to work correctly. Is that the case for you?
I’ve tried the SetTimer call in the game menu only, I don’t do it in the main menu.
I think it is a problem with UObject derived class. It works for AActor derived class.
I’m not sure it is a problem with leaving the map since the function FShooterIngameMenu::OnUIQuit() call the local player’s function LeaveGame() and return. Don’t leave any map, just sets a call-back with a timer that will execute the quit command.
I’ve tried within Visual Studio 201 in debug mode and launching the Editor. From the editor, I’ve launched the Standalone game.
Are you able to sets a timer within an UObject derived class ?
Sorry for not responding sooner, I lost track of this post. Is this something that is still giving you trouble? I was able to do some additional debugging on this today, and I noticed something odd about this. If I launch standalone directly into a level in Shooter Game (either Highrise or Sanctuary, the result was the same), then delayed quit never gets called as you mentioned. However, if I instead launch into the ShooterEntry map, which provides the main menu, then load into one of the levels, the delayed quit works correctly. I also noticed that the in-game menu is slightly different in that case as well.
There appears to be a difference in how this logic is handled depending on how you initially get into the level, either directly or by loading in from the main menu. Unfortunately I am not familiar enough with Shooter Game to determine why that is the case. I suspect that something may not be getting initialized correctly when launching directly into the level.