- Home /
Why my Thread stop working when I call another class?
Hi all, I create one Thread where I perform some socket.receive operation. From this Thread I want call another class (Jump) for perform an animation on my Humanoid. When I call this class my Thread seems stop working? How can I resolve this problem? I show you my code:
Connect class (where I create Thread):
using UnityEngine;
using System.Collections;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Net;
public class Connect : MonoBehaviour {
Jump jump;
// Use this for initialization
void Start () {
Thread connectThread = new Thread (connection);
connectThread.Start ();
}
// Update is called once per frame
void Update () {
}
void connection(){
StringBuilder sb = new StringBuilder ();
byte[] buffer_controllo = new byte[1024];
byte[] buffer_controllo2 = new byte[1024];
byte[] buffer_dati = new byte[1024];
int count_bytes;
//Esegue connessione
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Connect ("1.2.3.4", 2000);
// socket.ReceiveTimeout = 10;
Debug.Log ("connesso");
string element;
string element2;
string data;
count_bytes = socket.Receive(buffer_controllo);
element = (System.Text.Encoding.ASCII.GetString(buffer_controllo));
element = element.Substring (0, count_bytes);
sb.Append (element);
int count_bytes2 = socket.Receive (buffer_controllo2);
element2 = System.Text.Encoding.ASCII.GetString (buffer_controllo2);
element2 = element2.Substring (0, count_bytes2);
sb.Append (element2);
Debug.Log (sb.ToString());
if (sb.ToString().Equals ("*HELLO*READY")) {
//Abilita trasmissione dati
Debug.Log("sto inviando");
byte[] start_byte = Encoding.ASCII.GetBytes ("s");
socket.Send (start_byte);
}
else {
return;
}
string dati;
int Pressure1;
int Pressure2;
int soglia = 120;
// socket.ReceiveTimeout = 10;
while ((count_bytes = socket.Receive(buffer_dati,0,19,SocketFlags.None))>0) {
dati = System.Text.Encoding.ASCII.GetString (buffer_dati);
Debug.Log(dati);
if(dati.Length>=19){
Pressure1 = int.Parse(dati.Substring(10, 3), System.Globalization.NumberStyles.HexNumber);
Pressure2 = int.Parse(dati.Substring(13, 3), System.Globalization.NumberStyles.HexNumber);
if(Pressure1>soglia && Pressure2>soglia){
Debug.Log("salto");
jump.performJump("a");
}
}
}
}
}
andthis is my jump class code:
using UnityEngine;
using System.Collections;
public class Jump : MonoBehaviour {
AndroidJavaClass jc;
// Use this for initialization
void Start () {
// AndroidJNIHelper.debug = true;
// jc = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");
// AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject> ("currentActivity");
// AndroidJNI.AttachCurrentThread ();
// androidClass = new AndroidJavaClass("com.example.footm.Avatar");
}
// Update is called once per frame
void Update () {
}
public void performJump(string message){
//Void esecuzione salto
GameObject go2 = GameObject.Find ("myHumanoid");
Animator anim = go2.GetComponent<Animator> ();
anim.Play ("jump_1");
}
}
Other thread is not support Unity3D API, only used in the main thread. Your action command move to main thread
Answer by Bunny83 · Oct 21, 2014 at 11:34 AM
Well, the answer is simple. The Unity API is not thread safe and will throw an exception when used from a different thread than the main thread. All 3 lines inside your performJump method would throw that error. You have to synchronise your thread with the main thread by somehow scheduling the desired action on the main thread.
The easiest way to do so is to use the Loom class provided on Unity Gems (at the bottom of the post).
It allows you to schedule a piece of code from any thread to run on the main thread.
I resolve my problem follow another way. I create another C# script where I declare a public static bool isJump = false;
In my Jump class I remove performJump's method and add its code into void Update as follow:
void Update () {
if (State.isJump) {
GameObject go2 = GameObject.Find ("myHumanoid");
Animator anim = go2.GetComponent<Animator> ();
anim.Play ("jump_1");
}
}
Into my Connect class I remove jump.performJump() and add State.isJump=true;
when this variable become true I can do the jump animation.
This is very dangerous since you let two thread work on the same data at the same time. This could lead to race-conditions and might result in unpredictable errors. I strongly recommend you read some papers on threading and synchronising those.
thank you for reply. Now I am following another way. I remove the thread from Connect class and I write it into a java file. I export this java file as .jar . I transform this .jar in a dll. I import dll in Assets/Plugin/Android. Now I can call the class write in Java and use it.
Your answer
Follow this Question
Related Questions
Coroutine Death on Scene Change 3 Answers
Threads and serial port Bluetooth devices 0 Answers
Create GameObjects in Threads? 1 Answer
How does a thread work in a distributed environment? 0 Answers
C++ Callback in another thread 1 Answer