How can I change scenes with OSC input? Main thread?

I’m trying to advance to the next or previous level when I receive certain OSC input. I’m using OSC scripts from this tutorial, which all work fine until I try to change scenes and I get a “LoadLevelAsync can only be called from the main thread.” error.

I’m new to Unity, so I think I’m missing something pretty basic here, but as far as I’ve been able to find on Google, as long as I call Application.LoadLevel from within a function I should be ok. I’m doing that, but it’s not working.

Here’s my OSCreceiver script (everything else is unmodified from this github repo). What am I doing wrong?

//You can set these variables in the scene because they are public 
public var RemoteIP : String = "127.0.0.1";
public var SendToPort : int = 57131;
public var ListenerPort : int = 57130;
private var controller : Transform; 
private var handler : Osc;
static var messages : Array = [0.0,0.0,0.0,0.0,1.0];

public function Start () {
	//Initializes on start up to listen for messages
	//make sure this game object has both UDPPackIO and OSC script attached
	
	var udp : UDPPacketIO = GetComponent("UDPPacketIO");
	udp.init(RemoteIP, SendToPort, ListenerPort);
	handler = GetComponent("Osc");
	handler.init(udp);
			
	handler.SetAddressHandler("/3d/mod1", ListenEvent);
	handler.SetAddressHandler("/3d/mod2", ListenEvent);
	handler.SetAddressHandler("/3d/mod3", ListenEvent);
	handler.SetAddressHandler("/3d/mod4", ListenEvent);
	handler.SetAddressHandler("/3d/scenenext", ListenEvent);
	handler.SetAddressHandler("/3d/sceneprev", ListenEvent);
	// handler.SetAddressHandler("/3d/cam1", ListenEvent);
	// handler.SetAddressHandler("/3d/cam2", ListenEvent);
	// handler.SetAddressHandler("/3d/cam3", ListenEvent);
	// handler.SetAddressHandler("/3d/cam4", ListenEvent);
	// handler.SetAddressHandler("/3d/obj1next", ListenEvent);
	// handler.SetAddressHandler("/3d/obj1prev", ListenEvent);
	// handler.SetAddressHandler("/3d/obj2next", ListenEvent);
	// handler.SetAddressHandler("/3d/obj2prev", ListenEvent);
	// handler.SetAddressHandler("/3d/width", ListenEvent);
}

public function ListenEvent(oscMessage : OscMessage) : void {	
	switch(oscMessage.Address){
		case "/3d/mod1":		i = 0; messages *= oscMessage.Values[0]; break;*

_ case “/3d/mod2”: i = 1; messages = oscMessage.Values[0]; break;_
_ case “/3d/mod3”: i = 2; messages = oscMessage.Values[0]; break;
case “/3d/mod4”: i = 3; messages = oscMessage.Values[0]; break;
* case “/3d/scenenext”: nextScene(); break;
case “/3d/sceneprev”: prevScene(); break;
// case “/3d/cam1”: break;
// case “/3d/cam2”: break;
// case “/3d/cam3”: break;
// case “/3d/cam4”: break;
// case “/3d/obj1next”: break;
// case “/3d/obj1prev”: break;
// case “/3d/obj2next”: break;
// case “/3d/obj2prev”: break;
// case “/3d/eyewidth”: break;
}
}*_

function nextScene() {
* Application.LoadLevelAsync(Mathf.Clamp(Application.loadedLevel + 1, 0, Application.levelCount - 1));*
}

function prevScene() {
* Application.LoadLevelAsync(Mathf.Clamp(Application.loadedLevel - 1, 0, Application.levelCount - 1));*
}

Answered it myself: because the listenEvent function runs asynchronously from the main thread, I need to set a variable there and then make an Update() function that checks that variable and then sets the scene.

//You can set these variables in the scene because they are public 
public var RemoteIP : String = "127.0.0.1";
public var SendToPort : int;
public var ListenerPort : int = 57130;
private var controller : Transform; 
private var handler : Osc;
static var messages : Array = [0.0,0.0,0.0,0.0,1.0];
private var nextSceneGo : boolean;
private var prevSceneGo : boolean;
private var whichCam : GameObject;
private var newCam : GameObject;
static var cam1 : GameObject;
static var cam2 : GameObject;
static var cam3 : GameObject;
static var cam4 : GameObject;

public function Start () {
	cam1 = GameObject.Find("_Stereocam1");
	cam2 = GameObject.Find("_Stereocam2");
	cam3 = GameObject.Find("_Stereocam3");
	cam4 = GameObject.Find("_Stereocam4");
	whichCam = cam1;
	newCam = cam1;
	
	prevSceneGo = false;
	nextSceneGo = false;
	//Initializes on start up to listen for messages
	//make sure this game object has both UDPPackIO and OSC script attached
	var udp : UDPPacketIO = GetComponent("UDPPacketIO");
	udp.init(RemoteIP, SendToPort, ListenerPort);
	handler = GetComponent("Osc");
	handler.init(udp);
			
	handler.SetAddressHandler("/3d/mod1", ListenEvent);
	handler.SetAddressHandler("/3d/mod2", ListenEvent);
	handler.SetAddressHandler("/3d/mod3", ListenEvent);
	handler.SetAddressHandler("/3d/mod4", ListenEvent);
	handler.SetAddressHandler("/3d/scenenext", ListenEvent);
	handler.SetAddressHandler("/3d/sceneprev", ListenEvent);
	handler.SetAddressHandler("/3d/cam1", ListenEvent);
	handler.SetAddressHandler("/3d/cam2", ListenEvent);
	handler.SetAddressHandler("/3d/cam3", ListenEvent);
	handler.SetAddressHandler("/3d/cam4", ListenEvent);
	// handler.SetAddressHandler("/3d/obj1next", ListenEvent);
	// handler.SetAddressHandler("/3d/obj1prev", ListenEvent);
	// handler.SetAddressHandler("/3d/obj2next", ListenEvent);
	// handler.SetAddressHandler("/3d/obj2prev", ListenEvent);
	// handler.SetAddressHandler("/3d/width", ListenEvent);
}

public function Update() {
	if(nextSceneGo == true) {
		nextSceneGo = false;
		nextScene();
	}
	if(prevSceneGo == true) {
		prevSceneGo = false;
		prevScene();
	}
	if(newCam != whichCam) {
		switchCam(newCam);
		whichCam = newCam;
	}

}

public function ListenEvent(oscMessage : OscMessage) : void {	
	switch(oscMessage.Address){
		case "/3d/mod1":		i = 0; messages *= oscMessage.Values[0]; break;*

_ case “/3d/mod2”: i = 1; messages = oscMessage.Values[0]; break;_
_ case “/3d/mod3”: i = 2; messages = oscMessage.Values[0]; break;
case “/3d/mod4”: i = 3; messages = oscMessage.Values[0]; break;
* case “/3d/scenenext”: nextSceneGo = true; break;
case “/3d/sceneprev”: prevSceneGo = true; break;
case “/3d/cam1”: newCam = cam1; break;
case “/3d/cam2”: newCam = cam2; break;
case “/3d/cam3”: newCam = cam3; break;
case “/3d/cam4”: newCam = cam4; break;
// case “/3d/obj1next”: break;
// case “/3d/obj1prev”: break;
// case “/3d/obj2next”: break;
// case “/3d/obj2prev”: break;
// case “/3d/eyewidth”: break;
}
}*_

function switchCam(n) {
* whichCam.SetActiveRecursively(false);*
* whichCam.active = true;*
* newCam.SetActiveRecursively(true);*
}

function nextScene() {
* Application.LoadLevelAsync(Mathf.Clamp(Application.loadedLevel + 1, 0, Application.levelCount - 1));*
}

function prevScene() {
* Application.LoadLevelAsync(Mathf.Clamp(Application.loadedLevel - 1, 0, Application.levelCount - 1));*
}