Skip to content

Running Unity Specific Code on the Main Thread

Balroth edited this page May 17, 2019 · 5 revisions

We have created a helper class for you to be able to offload any logic to the main thread from a separate thread. This helper class is called MainThreadManager and there are 2 main ways that you can use this class. The entry point for both methods of use is the static method Run ; see the code snippets below for practical uses. The examples below emulate an RPC method's contents.

MainThreadManager.Run Function Pointer

public override void MyCustomRPC(object[] args)
{
	// Register the private function within this class to be called on the main thread
	MainThreadManager.Run(OtherFunction);
}

private void OtherFunction()
{
	Debug.Log("Hello World!");
}

You can see that the above example requires another accessible method in order to pass it into the main thread manager's Run method.

MainThreadManager.Run Lambda Expression

public override void MyCustomRPC(object[] args)
{
	// Setup a temporary method call (lambda expression) to be executed on the main thread
	MainThreadManager.Run(() => { Debug.Log("Hello World!"); });
}

The above is the preferred method

The lambda expression is a native C# feature that allows you to essentially create an inline function at runtime. Please see this website or the official documentation for more information on lambda expressions.

What does the Main Thread Manager do?

The Main Thread Manager is actually a pretty small and simple singleton class. When you send a method pointer or inline expression into the Run method it will be added to a queue. The Main Thread Manager is a Unity GameObject and will automatically create itself if one is not created already. By default every FixedUpdate for this object, it will check to see if there are any pending methods in the queue, if so it will run them and remove them from the queue. By running these methods in the FixedUpdate they are automatically ran on the main thread.

You can specify which Unity update method to run the lambda expression or method on by adding the second parameter.

To run the method/lamdba expression when Unity's Update runs you need to specify UpdateType.Update as the second parameter to MainThreadManager.Run()

public override void MyCustomRPC(object[] args)
{
	// Setup a temporary method call (lambda expression) to be executed on the main thread
	MainThreadManager.Run(() => { Debug.Log("Hello World!"); }, UpdateType.Update);
}

Automatic MainThreadManager.Run() on RPCs

If you have ticked the box UseMainThreadManager in the MultiplayerMenu (script, default in BeardedManStudios and default on the starting MultiplayerMenu Scene), then inside every RPC, the entire function is wrapped

MainThreadManager.Run(() => { your code });

For example, say you have this code:

// This is an RPC function made via the NetworkContractWizard, inside a network object
public void override PrintRPC(RpcArgs args)
{
    Debug.Log("Hello World!");
    Debug.Log("We are inside an RPC!");
}

When you tick/check the UseMainThreadManager checkbox (which is true by default), the code automatically becomes:

// This is an RPC function made via the NetworkContractWizard, inside a network object
public void override PrintRPC(RpcArgs args)
{
    MainThreadManager.Run(() => {
        Debug.Log("Hello World!");
        Debug.Log("We are inside an RPC!");
    });
    
}

There is no real reason to not use the automatic checkbox, unless you simply don't use Unity (See C# headless server), since MainThreadManager is essentially Unity's Main Thread.

However, do remember that this automatic MainThreadManager.Run() happens only inside an RPC.

sendRPC(RPC_PRINT_RPC, Receivers.All);

The above code, will not be automatically wrapped inside MainThreadManager.Run()
It may be obvious, but since this is documentations, it should be crystal-clear ;)

Home

Getting Started
Network Contract Wizard (NCW)
Network Object
Remote Procedure Calls (RPCs)
Unity Integration
Basic Network Samples
Scene Navigation
NetWorker
Master Server
Web Server
Netcoding Design Patterns
Troubleshooting
Miscellaneous
Clone this wiki locally
You can’t perform that action at this time.