diff --git a/ExampleProject/HelloWorld/Assets/Plugins/Sphero/NoSpheroConnectedView.cs b/ExampleProject/HelloWorld/Assets/Plugins/Sphero/NoSpheroConnectedView.cs
index cb3c09e..61a67d6 100644
--- a/ExampleProject/HelloWorld/Assets/Plugins/Sphero/NoSpheroConnectedView.cs
+++ b/ExampleProject/HelloWorld/Assets/Plugins/Sphero/NoSpheroConnectedView.cs
@@ -27,6 +27,13 @@ public class NoSpheroConnectedView : MonoBehaviour {
// UI Padding Variables
int m_ViewPadding = 20;
+
+ private ThreadSafeLoadLevel m_threadSafeLoadLevel;
+
+ void Awake()
+ {
+ m_threadSafeLoadLevel = ThreadSafeLoadLevel.Instance;
+ }
void Start () {
ViewSetup();
@@ -59,7 +66,10 @@ private void ReceiveNotificationMessage(object sender, SpheroDeviceMessenger.Mes
SpheroDeviceNotification message = (SpheroDeviceNotification)eventArgs.Message;
if( message.NotificationType == SpheroDeviceNotification.SpheroNotificationType.CONNECTED ) {
// Go to the desired scene
- Application.LoadLevel (m_NextLevel);
+ if (m_threadSafeLoadLevel != null)
+ {
+ m_threadSafeLoadLevel.LoadLevel(m_NextLevel);
+ }
}
}
@@ -125,7 +135,10 @@ void OnGUI() {
getASpheroButtonY = backgroundY+(backgroundHeight*0.85f) - (buttonHeight/2);
// If the get a Sphero button is clicked
if( GUI.Button (new Rect(getASpheroButtonX, getASpheroButtonY,buttonWidth,buttonHeight), "") ) {
- Application.LoadLevel("SpheroConnectionScene");
+ if (m_threadSafeLoadLevel != null)
+ {
+ m_threadSafeLoadLevel.LoadLevel("SpheroConnectionScene");
+ }
}
#endif
}
diff --git a/ExampleProject/HelloWorld/Assets/Plugins/Sphero/SpheroConnectionView.cs b/ExampleProject/HelloWorld/Assets/Plugins/Sphero/SpheroConnectionView.cs
index 82effdc..eef8666 100644
--- a/ExampleProject/HelloWorld/Assets/Plugins/Sphero/SpheroConnectionView.cs
+++ b/ExampleProject/HelloWorld/Assets/Plugins/Sphero/SpheroConnectionView.cs
@@ -60,6 +60,8 @@ public class SpheroConnectionView : MonoBehaviour {
Vector2 windowMargin = new Vector2(0,0);
Vector2 listMargin = new Vector2(40,40);
private Rect windowRect;
+
+ private ThreadSafeLoadLevel m_threadSafeLoadLevel;
/* Use this to initialize the view */
private void ViewSetup() {
@@ -72,6 +74,11 @@ private void ViewSetup() {
// Display that it doesn't work with these platforms?
#endif
}
+
+ void Awake()
+ {
+ m_threadSafeLoadLevel = ThreadSafeLoadLevel.Instance;
+ }
/* Use these for initialization */
void Start () {
@@ -106,7 +113,10 @@ void SetupIOS() {
*/
void CheckForSpheroConnection() {
if( m_SpheroProvider.GetConnectedSpheros().Length == 0 ) {
- Application.LoadLevel("NoSpheroConnectedScene");
+ if (m_threadSafeLoadLevel != null)
+ {
+ m_threadSafeLoadLevel.LoadLevel("NoSpheroConnectedScene");
+ }
}
}
@@ -157,7 +167,10 @@ private void ReceiveNotificationMessage(object sender, SpheroDeviceMessenger.Mes
if( !m_MultipleSpheros ) {
m_Title = "Connection Success";
SpheroDeviceMessenger.SharedInstance.NotificationReceived -= ReceiveNotificationMessage;
- Application.LoadLevel(m_NextLevel);
+ if (m_threadSafeLoadLevel != null)
+ {
+ m_threadSafeLoadLevel.LoadLevel(m_NextLevel);
+ }
}
}
else if( message.NotificationType == SpheroDeviceNotification.SpheroNotificationType.CONNECTION_FAILED ) {
@@ -281,7 +294,10 @@ void OnGUI() {
// Check if we are done adding robots
if( buttonLabel.Equals("Done") ){
SpheroDeviceMessenger.SharedInstance.NotificationReceived -= ReceiveNotificationMessage;
- Application.LoadLevel(m_NextLevel);
+ if (m_threadSafeLoadLevel != null)
+ {
+ m_threadSafeLoadLevel.LoadLevel(m_NextLevel);
+ }
}
// Check if we have a Sphero connected
else if( m_SpheroLabelSelected >= 0 ) {
diff --git a/ExampleProject/HelloWorld/Assets/Plugins/Sphero/ThreadSafeLoadLevel.cs b/ExampleProject/HelloWorld/Assets/Plugins/Sphero/ThreadSafeLoadLevel.cs
new file mode 100644
index 0000000..fc2426e
--- /dev/null
+++ b/ExampleProject/HelloWorld/Assets/Plugins/Sphero/ThreadSafeLoadLevel.cs
@@ -0,0 +1,82 @@
+using System.Threading;
+using UnityEngine;
+
+///
+/// The goal of this class is to let you load levels (from the Sphero callbacks) in a way that
+/// doesn't try to make Unity calls on a thread other than the Unity thread. Unity takes issue with
+/// this and will throw a crashing-tantrum.
+///
+public class ThreadSafeLoadLevel : MonoBehaviour
+{
+ #region Static instance management
+ ///
+ /// Static instance of this script
+ ///
+ private static ThreadSafeLoadLevel s_instance;
+
+ ///
+ /// No creating an instance after OnApplicationQuit is called - can get funky in the editor
+ ///
+ private static bool m_exiting;
+
+ ///
+ /// Gets the static instance of his script. This is *NOT* thread safe. Call it from Unity's
+ /// thread (creates a Unity object)
+ ///
+ public static ThreadSafeLoadLevel Instance
+ {
+ get
+ {
+ if (s_instance == null && !m_exiting)
+ {
+ var go = new GameObject("ThreadSafeLoadLevel");
+ s_instance = go.AddComponent();
+ }
+ return s_instance;
+ }
+ }
+ #endregion
+
+ ///
+ /// An object to lock on
+ ///
+ private readonly Object m_lock = new Object();
+
+ ///
+ /// The level we want to load
+ ///
+ private string m_levelToLoad;
+
+ #region Unity-style callbacks
+ void Update()
+ {
+ // non-blocking lock acquire
+ if (Monitor.TryEnter(m_lock))
+ {
+ if (!string.IsNullOrEmpty(m_levelToLoad))
+ {
+ Application.LoadLevel(m_levelToLoad);
+ }
+
+ Monitor.Exit(m_lock);
+ }
+ }
+
+ void OnApplicationQuit()
+ {
+ m_exiting = true;
+ }
+ #endregion
+
+ ///
+ /// Loads the given level by name
+ ///
+ /// a level we wish to load
+ public void LoadLevel(string levelName)
+ {
+ lock (m_lock)
+ {
+ m_levelToLoad = levelName;
+ }
+ }
+}
diff --git a/ExampleProject/HelloWorld/Assets/Plugins/Sphero/ThreadSafeLoadLevel.cs.meta b/ExampleProject/HelloWorld/Assets/Plugins/Sphero/ThreadSafeLoadLevel.cs.meta
new file mode 100644
index 0000000..0cca37d
--- /dev/null
+++ b/ExampleProject/HelloWorld/Assets/Plugins/Sphero/ThreadSafeLoadLevel.cs.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 51bc1e102d852f54ba6e77fee637e2d6
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/ExampleProject/SensorStreaming/Assets/Plugins/Sphero/NoSpheroConnectedView.cs b/ExampleProject/SensorStreaming/Assets/Plugins/Sphero/NoSpheroConnectedView.cs
index cb3c09e..61a67d6 100644
--- a/ExampleProject/SensorStreaming/Assets/Plugins/Sphero/NoSpheroConnectedView.cs
+++ b/ExampleProject/SensorStreaming/Assets/Plugins/Sphero/NoSpheroConnectedView.cs
@@ -27,6 +27,13 @@ public class NoSpheroConnectedView : MonoBehaviour {
// UI Padding Variables
int m_ViewPadding = 20;
+
+ private ThreadSafeLoadLevel m_threadSafeLoadLevel;
+
+ void Awake()
+ {
+ m_threadSafeLoadLevel = ThreadSafeLoadLevel.Instance;
+ }
void Start () {
ViewSetup();
@@ -59,7 +66,10 @@ private void ReceiveNotificationMessage(object sender, SpheroDeviceMessenger.Mes
SpheroDeviceNotification message = (SpheroDeviceNotification)eventArgs.Message;
if( message.NotificationType == SpheroDeviceNotification.SpheroNotificationType.CONNECTED ) {
// Go to the desired scene
- Application.LoadLevel (m_NextLevel);
+ if (m_threadSafeLoadLevel != null)
+ {
+ m_threadSafeLoadLevel.LoadLevel(m_NextLevel);
+ }
}
}
@@ -125,7 +135,10 @@ void OnGUI() {
getASpheroButtonY = backgroundY+(backgroundHeight*0.85f) - (buttonHeight/2);
// If the get a Sphero button is clicked
if( GUI.Button (new Rect(getASpheroButtonX, getASpheroButtonY,buttonWidth,buttonHeight), "") ) {
- Application.LoadLevel("SpheroConnectionScene");
+ if (m_threadSafeLoadLevel != null)
+ {
+ m_threadSafeLoadLevel.LoadLevel("SpheroConnectionScene");
+ }
}
#endif
}
diff --git a/ExampleProject/SensorStreaming/Assets/Plugins/Sphero/SpheroConnectionView.cs b/ExampleProject/SensorStreaming/Assets/Plugins/Sphero/SpheroConnectionView.cs
index 82effdc..eef8666 100644
--- a/ExampleProject/SensorStreaming/Assets/Plugins/Sphero/SpheroConnectionView.cs
+++ b/ExampleProject/SensorStreaming/Assets/Plugins/Sphero/SpheroConnectionView.cs
@@ -60,6 +60,8 @@ public class SpheroConnectionView : MonoBehaviour {
Vector2 windowMargin = new Vector2(0,0);
Vector2 listMargin = new Vector2(40,40);
private Rect windowRect;
+
+ private ThreadSafeLoadLevel m_threadSafeLoadLevel;
/* Use this to initialize the view */
private void ViewSetup() {
@@ -72,6 +74,11 @@ private void ViewSetup() {
// Display that it doesn't work with these platforms?
#endif
}
+
+ void Awake()
+ {
+ m_threadSafeLoadLevel = ThreadSafeLoadLevel.Instance;
+ }
/* Use these for initialization */
void Start () {
@@ -106,7 +113,10 @@ void SetupIOS() {
*/
void CheckForSpheroConnection() {
if( m_SpheroProvider.GetConnectedSpheros().Length == 0 ) {
- Application.LoadLevel("NoSpheroConnectedScene");
+ if (m_threadSafeLoadLevel != null)
+ {
+ m_threadSafeLoadLevel.LoadLevel("NoSpheroConnectedScene");
+ }
}
}
@@ -157,7 +167,10 @@ private void ReceiveNotificationMessage(object sender, SpheroDeviceMessenger.Mes
if( !m_MultipleSpheros ) {
m_Title = "Connection Success";
SpheroDeviceMessenger.SharedInstance.NotificationReceived -= ReceiveNotificationMessage;
- Application.LoadLevel(m_NextLevel);
+ if (m_threadSafeLoadLevel != null)
+ {
+ m_threadSafeLoadLevel.LoadLevel(m_NextLevel);
+ }
}
}
else if( message.NotificationType == SpheroDeviceNotification.SpheroNotificationType.CONNECTION_FAILED ) {
@@ -281,7 +294,10 @@ void OnGUI() {
// Check if we are done adding robots
if( buttonLabel.Equals("Done") ){
SpheroDeviceMessenger.SharedInstance.NotificationReceived -= ReceiveNotificationMessage;
- Application.LoadLevel(m_NextLevel);
+ if (m_threadSafeLoadLevel != null)
+ {
+ m_threadSafeLoadLevel.LoadLevel(m_NextLevel);
+ }
}
// Check if we have a Sphero connected
else if( m_SpheroLabelSelected >= 0 ) {
diff --git a/ExampleProject/SensorStreaming/Assets/Plugins/Sphero/ThreadSafeLoadLevel.cs b/ExampleProject/SensorStreaming/Assets/Plugins/Sphero/ThreadSafeLoadLevel.cs
new file mode 100644
index 0000000..fc2426e
--- /dev/null
+++ b/ExampleProject/SensorStreaming/Assets/Plugins/Sphero/ThreadSafeLoadLevel.cs
@@ -0,0 +1,82 @@
+using System.Threading;
+using UnityEngine;
+
+///
+/// The goal of this class is to let you load levels (from the Sphero callbacks) in a way that
+/// doesn't try to make Unity calls on a thread other than the Unity thread. Unity takes issue with
+/// this and will throw a crashing-tantrum.
+///
+public class ThreadSafeLoadLevel : MonoBehaviour
+{
+ #region Static instance management
+ ///
+ /// Static instance of this script
+ ///
+ private static ThreadSafeLoadLevel s_instance;
+
+ ///
+ /// No creating an instance after OnApplicationQuit is called - can get funky in the editor
+ ///
+ private static bool m_exiting;
+
+ ///
+ /// Gets the static instance of his script. This is *NOT* thread safe. Call it from Unity's
+ /// thread (creates a Unity object)
+ ///
+ public static ThreadSafeLoadLevel Instance
+ {
+ get
+ {
+ if (s_instance == null && !m_exiting)
+ {
+ var go = new GameObject("ThreadSafeLoadLevel");
+ s_instance = go.AddComponent();
+ }
+ return s_instance;
+ }
+ }
+ #endregion
+
+ ///
+ /// An object to lock on
+ ///
+ private readonly Object m_lock = new Object();
+
+ ///
+ /// The level we want to load
+ ///
+ private string m_levelToLoad;
+
+ #region Unity-style callbacks
+ void Update()
+ {
+ // non-blocking lock acquire
+ if (Monitor.TryEnter(m_lock))
+ {
+ if (!string.IsNullOrEmpty(m_levelToLoad))
+ {
+ Application.LoadLevel(m_levelToLoad);
+ }
+
+ Monitor.Exit(m_lock);
+ }
+ }
+
+ void OnApplicationQuit()
+ {
+ m_exiting = true;
+ }
+ #endregion
+
+ ///
+ /// Loads the given level by name
+ ///
+ /// a level we wish to load
+ public void LoadLevel(string levelName)
+ {
+ lock (m_lock)
+ {
+ m_levelToLoad = levelName;
+ }
+ }
+}
diff --git a/ExampleProject/SensorStreaming/Assets/Plugins/Sphero/ThreadSafeLoadLevel.cs.meta b/ExampleProject/SensorStreaming/Assets/Plugins/Sphero/ThreadSafeLoadLevel.cs.meta
new file mode 100644
index 0000000..0cca37d
--- /dev/null
+++ b/ExampleProject/SensorStreaming/Assets/Plugins/Sphero/ThreadSafeLoadLevel.cs.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 51bc1e102d852f54ba6e77fee637e2d6
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/ExampleProject/SensorStreaming/Assets/Scripts/UpdateValues.cs b/ExampleProject/SensorStreaming/Assets/Scripts/UpdateValues.cs
index efcaae0..06630dc 100644
--- a/ExampleProject/SensorStreaming/Assets/Scripts/UpdateValues.cs
+++ b/ExampleProject/SensorStreaming/Assets/Scripts/UpdateValues.cs
@@ -18,14 +18,26 @@ public class UpdateValues: MonoBehaviour {
private float q1 = 1.0f;
private float q2 = 1.0f;
private float q3 = 1.0f;
+
+ private ThreadSafeLoadLevel m_threadSafeLoadLevel;
/* Use this for initialization */
void ViewSetup() {
// Get Connected Sphero
SpheroDeviceMessenger.SharedInstance.NotificationReceived +=
ReceiveNotificationMessage;
- if( SpheroProvider.GetSharedProvider().GetConnectedSpheros().Length == 0 )
- Application.LoadLevel("SpheroConnectionScene");
+ if (SpheroProvider.GetSharedProvider().GetConnectedSpheros().Length == 0)
+ {
+ if (m_threadSafeLoadLevel != null)
+ {
+ m_threadSafeLoadLevel.LoadLevel("SpheroConnectionScene");
+ }
+ }
+ }
+
+ void Awake()
+ {
+ m_threadSafeLoadLevel = ThreadSafeLoadLevel.Instance;
}
// Use this for initialization
@@ -132,7 +144,10 @@ private void ReceiveNotificationMessage(object sender, SpheroDeviceMessenger.Mes
if( message.NotificationType == SpheroDeviceNotification.SpheroNotificationType.DISCONNECTED ) {
notifiedSphero.ConnectionState = Sphero.Connection_State.Disconnected;
streaming = false;
- Application.LoadLevel("NoSpheroConnectedScene");
+ if (m_threadSafeLoadLevel != null)
+ {
+ m_threadSafeLoadLevel.LoadLevel("NoSpheroConnectedScene");
+ }
}
}
}
diff --git a/ExampleProject/SensorStreaming/ProjectSettings/ProjectSettings.asset b/ExampleProject/SensorStreaming/ProjectSettings/ProjectSettings.asset
index a8e3394..789ae6b 100644
Binary files a/ExampleProject/SensorStreaming/ProjectSettings/ProjectSettings.asset and b/ExampleProject/SensorStreaming/ProjectSettings/ProjectSettings.asset differ
diff --git a/ExampleProject/UISample/Assets/Plugins/Sphero/NoSpheroConnectedView.cs b/ExampleProject/UISample/Assets/Plugins/Sphero/NoSpheroConnectedView.cs
index cb3c09e..61a67d6 100644
--- a/ExampleProject/UISample/Assets/Plugins/Sphero/NoSpheroConnectedView.cs
+++ b/ExampleProject/UISample/Assets/Plugins/Sphero/NoSpheroConnectedView.cs
@@ -27,6 +27,13 @@ public class NoSpheroConnectedView : MonoBehaviour {
// UI Padding Variables
int m_ViewPadding = 20;
+
+ private ThreadSafeLoadLevel m_threadSafeLoadLevel;
+
+ void Awake()
+ {
+ m_threadSafeLoadLevel = ThreadSafeLoadLevel.Instance;
+ }
void Start () {
ViewSetup();
@@ -59,7 +66,10 @@ private void ReceiveNotificationMessage(object sender, SpheroDeviceMessenger.Mes
SpheroDeviceNotification message = (SpheroDeviceNotification)eventArgs.Message;
if( message.NotificationType == SpheroDeviceNotification.SpheroNotificationType.CONNECTED ) {
// Go to the desired scene
- Application.LoadLevel (m_NextLevel);
+ if (m_threadSafeLoadLevel != null)
+ {
+ m_threadSafeLoadLevel.LoadLevel(m_NextLevel);
+ }
}
}
@@ -125,7 +135,10 @@ void OnGUI() {
getASpheroButtonY = backgroundY+(backgroundHeight*0.85f) - (buttonHeight/2);
// If the get a Sphero button is clicked
if( GUI.Button (new Rect(getASpheroButtonX, getASpheroButtonY,buttonWidth,buttonHeight), "") ) {
- Application.LoadLevel("SpheroConnectionScene");
+ if (m_threadSafeLoadLevel != null)
+ {
+ m_threadSafeLoadLevel.LoadLevel("SpheroConnectionScene");
+ }
}
#endif
}
diff --git a/ExampleProject/UISample/Assets/Plugins/Sphero/SpheroConnectionView.cs b/ExampleProject/UISample/Assets/Plugins/Sphero/SpheroConnectionView.cs
index 82effdc..eef8666 100644
--- a/ExampleProject/UISample/Assets/Plugins/Sphero/SpheroConnectionView.cs
+++ b/ExampleProject/UISample/Assets/Plugins/Sphero/SpheroConnectionView.cs
@@ -60,6 +60,8 @@ public class SpheroConnectionView : MonoBehaviour {
Vector2 windowMargin = new Vector2(0,0);
Vector2 listMargin = new Vector2(40,40);
private Rect windowRect;
+
+ private ThreadSafeLoadLevel m_threadSafeLoadLevel;
/* Use this to initialize the view */
private void ViewSetup() {
@@ -72,6 +74,11 @@ private void ViewSetup() {
// Display that it doesn't work with these platforms?
#endif
}
+
+ void Awake()
+ {
+ m_threadSafeLoadLevel = ThreadSafeLoadLevel.Instance;
+ }
/* Use these for initialization */
void Start () {
@@ -106,7 +113,10 @@ void SetupIOS() {
*/
void CheckForSpheroConnection() {
if( m_SpheroProvider.GetConnectedSpheros().Length == 0 ) {
- Application.LoadLevel("NoSpheroConnectedScene");
+ if (m_threadSafeLoadLevel != null)
+ {
+ m_threadSafeLoadLevel.LoadLevel("NoSpheroConnectedScene");
+ }
}
}
@@ -157,7 +167,10 @@ private void ReceiveNotificationMessage(object sender, SpheroDeviceMessenger.Mes
if( !m_MultipleSpheros ) {
m_Title = "Connection Success";
SpheroDeviceMessenger.SharedInstance.NotificationReceived -= ReceiveNotificationMessage;
- Application.LoadLevel(m_NextLevel);
+ if (m_threadSafeLoadLevel != null)
+ {
+ m_threadSafeLoadLevel.LoadLevel(m_NextLevel);
+ }
}
}
else if( message.NotificationType == SpheroDeviceNotification.SpheroNotificationType.CONNECTION_FAILED ) {
@@ -281,7 +294,10 @@ void OnGUI() {
// Check if we are done adding robots
if( buttonLabel.Equals("Done") ){
SpheroDeviceMessenger.SharedInstance.NotificationReceived -= ReceiveNotificationMessage;
- Application.LoadLevel(m_NextLevel);
+ if (m_threadSafeLoadLevel != null)
+ {
+ m_threadSafeLoadLevel.LoadLevel(m_NextLevel);
+ }
}
// Check if we have a Sphero connected
else if( m_SpheroLabelSelected >= 0 ) {
diff --git a/ExampleProject/UISample/Assets/Plugins/Sphero/ThreadSafeLoadLevel.cs b/ExampleProject/UISample/Assets/Plugins/Sphero/ThreadSafeLoadLevel.cs
new file mode 100644
index 0000000..fc2426e
--- /dev/null
+++ b/ExampleProject/UISample/Assets/Plugins/Sphero/ThreadSafeLoadLevel.cs
@@ -0,0 +1,82 @@
+using System.Threading;
+using UnityEngine;
+
+///
+/// The goal of this class is to let you load levels (from the Sphero callbacks) in a way that
+/// doesn't try to make Unity calls on a thread other than the Unity thread. Unity takes issue with
+/// this and will throw a crashing-tantrum.
+///
+public class ThreadSafeLoadLevel : MonoBehaviour
+{
+ #region Static instance management
+ ///
+ /// Static instance of this script
+ ///
+ private static ThreadSafeLoadLevel s_instance;
+
+ ///
+ /// No creating an instance after OnApplicationQuit is called - can get funky in the editor
+ ///
+ private static bool m_exiting;
+
+ ///
+ /// Gets the static instance of his script. This is *NOT* thread safe. Call it from Unity's
+ /// thread (creates a Unity object)
+ ///
+ public static ThreadSafeLoadLevel Instance
+ {
+ get
+ {
+ if (s_instance == null && !m_exiting)
+ {
+ var go = new GameObject("ThreadSafeLoadLevel");
+ s_instance = go.AddComponent();
+ }
+ return s_instance;
+ }
+ }
+ #endregion
+
+ ///
+ /// An object to lock on
+ ///
+ private readonly Object m_lock = new Object();
+
+ ///
+ /// The level we want to load
+ ///
+ private string m_levelToLoad;
+
+ #region Unity-style callbacks
+ void Update()
+ {
+ // non-blocking lock acquire
+ if (Monitor.TryEnter(m_lock))
+ {
+ if (!string.IsNullOrEmpty(m_levelToLoad))
+ {
+ Application.LoadLevel(m_levelToLoad);
+ }
+
+ Monitor.Exit(m_lock);
+ }
+ }
+
+ void OnApplicationQuit()
+ {
+ m_exiting = true;
+ }
+ #endregion
+
+ ///
+ /// Loads the given level by name
+ ///
+ /// a level we wish to load
+ public void LoadLevel(string levelName)
+ {
+ lock (m_lock)
+ {
+ m_levelToLoad = levelName;
+ }
+ }
+}
diff --git a/ExampleProject/UISample/Assets/Plugins/Sphero/ThreadSafeLoadLevel.cs.meta b/ExampleProject/UISample/Assets/Plugins/Sphero/ThreadSafeLoadLevel.cs.meta
new file mode 100644
index 0000000..0cca37d
--- /dev/null
+++ b/ExampleProject/UISample/Assets/Plugins/Sphero/ThreadSafeLoadLevel.cs.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 51bc1e102d852f54ba6e77fee637e2d6
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/Plugins/Sphero/NoSpheroConnectedView.cs b/Plugins/Sphero/NoSpheroConnectedView.cs
index cb3c09e..61a67d6 100644
--- a/Plugins/Sphero/NoSpheroConnectedView.cs
+++ b/Plugins/Sphero/NoSpheroConnectedView.cs
@@ -27,6 +27,13 @@ public class NoSpheroConnectedView : MonoBehaviour {
// UI Padding Variables
int m_ViewPadding = 20;
+
+ private ThreadSafeLoadLevel m_threadSafeLoadLevel;
+
+ void Awake()
+ {
+ m_threadSafeLoadLevel = ThreadSafeLoadLevel.Instance;
+ }
void Start () {
ViewSetup();
@@ -59,7 +66,10 @@ private void ReceiveNotificationMessage(object sender, SpheroDeviceMessenger.Mes
SpheroDeviceNotification message = (SpheroDeviceNotification)eventArgs.Message;
if( message.NotificationType == SpheroDeviceNotification.SpheroNotificationType.CONNECTED ) {
// Go to the desired scene
- Application.LoadLevel (m_NextLevel);
+ if (m_threadSafeLoadLevel != null)
+ {
+ m_threadSafeLoadLevel.LoadLevel(m_NextLevel);
+ }
}
}
@@ -125,7 +135,10 @@ void OnGUI() {
getASpheroButtonY = backgroundY+(backgroundHeight*0.85f) - (buttonHeight/2);
// If the get a Sphero button is clicked
if( GUI.Button (new Rect(getASpheroButtonX, getASpheroButtonY,buttonWidth,buttonHeight), "") ) {
- Application.LoadLevel("SpheroConnectionScene");
+ if (m_threadSafeLoadLevel != null)
+ {
+ m_threadSafeLoadLevel.LoadLevel("SpheroConnectionScene");
+ }
}
#endif
}
diff --git a/Plugins/Sphero/SpheroConnectionView.cs b/Plugins/Sphero/SpheroConnectionView.cs
index 82effdc..eef8666 100644
--- a/Plugins/Sphero/SpheroConnectionView.cs
+++ b/Plugins/Sphero/SpheroConnectionView.cs
@@ -60,6 +60,8 @@ public class SpheroConnectionView : MonoBehaviour {
Vector2 windowMargin = new Vector2(0,0);
Vector2 listMargin = new Vector2(40,40);
private Rect windowRect;
+
+ private ThreadSafeLoadLevel m_threadSafeLoadLevel;
/* Use this to initialize the view */
private void ViewSetup() {
@@ -72,6 +74,11 @@ private void ViewSetup() {
// Display that it doesn't work with these platforms?
#endif
}
+
+ void Awake()
+ {
+ m_threadSafeLoadLevel = ThreadSafeLoadLevel.Instance;
+ }
/* Use these for initialization */
void Start () {
@@ -106,7 +113,10 @@ void SetupIOS() {
*/
void CheckForSpheroConnection() {
if( m_SpheroProvider.GetConnectedSpheros().Length == 0 ) {
- Application.LoadLevel("NoSpheroConnectedScene");
+ if (m_threadSafeLoadLevel != null)
+ {
+ m_threadSafeLoadLevel.LoadLevel("NoSpheroConnectedScene");
+ }
}
}
@@ -157,7 +167,10 @@ private void ReceiveNotificationMessage(object sender, SpheroDeviceMessenger.Mes
if( !m_MultipleSpheros ) {
m_Title = "Connection Success";
SpheroDeviceMessenger.SharedInstance.NotificationReceived -= ReceiveNotificationMessage;
- Application.LoadLevel(m_NextLevel);
+ if (m_threadSafeLoadLevel != null)
+ {
+ m_threadSafeLoadLevel.LoadLevel(m_NextLevel);
+ }
}
}
else if( message.NotificationType == SpheroDeviceNotification.SpheroNotificationType.CONNECTION_FAILED ) {
@@ -281,7 +294,10 @@ void OnGUI() {
// Check if we are done adding robots
if( buttonLabel.Equals("Done") ){
SpheroDeviceMessenger.SharedInstance.NotificationReceived -= ReceiveNotificationMessage;
- Application.LoadLevel(m_NextLevel);
+ if (m_threadSafeLoadLevel != null)
+ {
+ m_threadSafeLoadLevel.LoadLevel(m_NextLevel);
+ }
}
// Check if we have a Sphero connected
else if( m_SpheroLabelSelected >= 0 ) {
diff --git a/Plugins/Sphero/ThreadSafeLoadLevel.cs b/Plugins/Sphero/ThreadSafeLoadLevel.cs
new file mode 100644
index 0000000..fc2426e
--- /dev/null
+++ b/Plugins/Sphero/ThreadSafeLoadLevel.cs
@@ -0,0 +1,82 @@
+using System.Threading;
+using UnityEngine;
+
+///
+/// The goal of this class is to let you load levels (from the Sphero callbacks) in a way that
+/// doesn't try to make Unity calls on a thread other than the Unity thread. Unity takes issue with
+/// this and will throw a crashing-tantrum.
+///
+public class ThreadSafeLoadLevel : MonoBehaviour
+{
+ #region Static instance management
+ ///
+ /// Static instance of this script
+ ///
+ private static ThreadSafeLoadLevel s_instance;
+
+ ///
+ /// No creating an instance after OnApplicationQuit is called - can get funky in the editor
+ ///
+ private static bool m_exiting;
+
+ ///
+ /// Gets the static instance of his script. This is *NOT* thread safe. Call it from Unity's
+ /// thread (creates a Unity object)
+ ///
+ public static ThreadSafeLoadLevel Instance
+ {
+ get
+ {
+ if (s_instance == null && !m_exiting)
+ {
+ var go = new GameObject("ThreadSafeLoadLevel");
+ s_instance = go.AddComponent();
+ }
+ return s_instance;
+ }
+ }
+ #endregion
+
+ ///
+ /// An object to lock on
+ ///
+ private readonly Object m_lock = new Object();
+
+ ///
+ /// The level we want to load
+ ///
+ private string m_levelToLoad;
+
+ #region Unity-style callbacks
+ void Update()
+ {
+ // non-blocking lock acquire
+ if (Monitor.TryEnter(m_lock))
+ {
+ if (!string.IsNullOrEmpty(m_levelToLoad))
+ {
+ Application.LoadLevel(m_levelToLoad);
+ }
+
+ Monitor.Exit(m_lock);
+ }
+ }
+
+ void OnApplicationQuit()
+ {
+ m_exiting = true;
+ }
+ #endregion
+
+ ///
+ /// Loads the given level by name
+ ///
+ /// a level we wish to load
+ public void LoadLevel(string levelName)
+ {
+ lock (m_lock)
+ {
+ m_levelToLoad = levelName;
+ }
+ }
+}
diff --git a/Plugins/Sphero/ThreadSafeLoadLevel.cs.meta b/Plugins/Sphero/ThreadSafeLoadLevel.cs.meta
new file mode 100644
index 0000000..0cca37d
--- /dev/null
+++ b/Plugins/Sphero/ThreadSafeLoadLevel.cs.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 51bc1e102d852f54ba6e77fee637e2d6
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData: