How do I resolve, get_isActiveAndEnabled can only be called from the main thread error
below is my script that i have attached to an empty game object. I made sure to assign the dropdown and text fields to the respective object accordingly(In the properties inspector).
below is a copy of my class.
 using UnityEngine;
 using UnityEngine.UI;
 using System.Collections;
 
 //Access the DarkRift namespace
 using DarkRift;
 using System;
 using System.Net.Sockets;
 using System.Timers;
 
 public class Manager : MonoBehaviour {
 
     public Dropdown dropdown;
 
     public Text myText;
 
     public Timer timer;
 
     public string serverSelection = "";
 
     public string serverIP = "";
 
     // Use this for initialization
     void Start () {
     
     }
     
     // Update is called once per frame
     void Update () {
     
     }
     public void connectButtonClickHandler()
     {
         print("Connecting to " + serverIP.ToString());
 
         //attempt to connect to the server.
         //Connect to the DarkRift Server using the Ip specified (will hang until connected or timeout)
         try
         {
             DarkRiftAPI.Connect (serverIP);
         } catch(Exception ex)
         {
             print("Cannot connect to. " + serverIP.ToString());
             print("Message: " + ex.Message);
         }
 
         //Setup a receiver so we can create players when told to.
         DarkRiftAPI.onDataDetailed += ReceiveData;
 
         //Tell others that we've entered the game and to instantiate a player object for us.
         if (DarkRiftAPI.isConnected)
         {
             print("Connected to server");
             //Get everyone else to tell us to spawn them a player (this doesn't need the data field so just put whatever)
             //DarkRiftAPI.SendMessageToOthers (TagIndex.Controller, TagIndex.ControllerSubjects.JoinMessage, "hi");
             //Then tell them to spawn us a player! (this time the data is the spawn position)
             //DarkRiftAPI.SendMessageToAll (TagIndex.Controller, TagIndex.ControllerSubjects.SpawnPlayer, new Vector3(0f,0f,0f));
         }
         else
             print("Failed to connect to DarkRift Server!");
 
             //display a message
             myText.text = "Failed to connect to server: " + serverIP.ToString();
 
             //set a timer that makes the message dissapear eventually
             timer = new Timer();
             timer.Interval = 3000;
             timer.AutoReset = false;
             timer.Elapsed += onTimerTick;
             //start the timer
             timer.Start();
 
             //go back to Connect screen
 
     }
     public void onTimerTick(System.Object source, ElapsedEventArgs e)
     {
         print("tick!");
         //empty the error text
         myText.text = "";
     }
     public void onServerSelectionChange()
     {
         print("Changed..!");
 
         if(dropdown.value == 0)
         {
             //Canada selected
             serverSelection = "Canada";
             serverIP = "127.0.0.1";
             print("Canada selected!");
         } else if(dropdown.value == 1)
         {
             //United States selected
             serverSelection = "United States";
             serverIP = "google.com";
             print("United States selected!");
         }
     }
     void ReceiveData (ushort senderID, byte tag, ushort subject, object data)
     {
         print("data received!");
         //When any data is received it will be passed here, 
         //we then need to process it if it's got a tag of 0 and, if 
         //so, create an object. This is where you'd handle most admin 
         //stuff like that.
 
         //Ok, if data has a Controller tag then it's for us
 //        if (tag == TagIndex.Controller)
 //        {
 //            //If a player has joined tell them to give us a player
 ////            if (subject == TagIndex.ControllerSubjects.JoinMessage) 
 ////            {
 ////                //Basically reply to them.
 //////                DarkRiftAPI.SendMessageToID (senderID, TagIndex.Controller, TagIndex.ControllerSubjects.SpawnPlayer, player.position);
 ////            }
 //
 //            //Then if it has a spawn subject we need to spawn a player
 ////            if (subject == TagIndex.ControllerSubjects.SpawnPlayer)
 ////            {
 ////                //Instantiate the player
 ////                //GameObject clone = (GameObject)Instantiate (playerObject, (Vector3)data, Quaternion.identity);
 ////                //Tell the network player who owns it so it tunes into the right updates.
 ////                //clone.GetComponent<NetworkPlayer>().networkID = senderID;
 ////
 ////                //If it's our player being created allow control and set the reference
 //////                if (senderID == DarkRiftAPI.id)
 //////                {
 //////                    //clone.GetComponent<Player>().isControllable = true;
 //////                   // player = clone.transform;
 //////                }
 ////            }
 //        }
     }
 }
 
The problem happens in my timer elapsed event handler, on the below line when i try to set the Text's text property. I also have a click button handler in there as you can see.
myText.text = "";
Answer by EuanHollidge · Mar 17, 2017 at 11:22 PM
Very simply from what I can tell you are using another thread to connect to the server. Since unity isn't technically thread compatible, anything other than the usual C# you can't do in a thread. What I would recommend doing is creating a String. Set the string = to what you were setting myText.text to. Then in Update() set myText.text = equal to the string either each frame or have a boolean set up so that it will only update when it changes. Here's the code :
  using UnityEngine;
  using UnityEngine.UI;
  using System.Collections;
  
  //Access the DarkRift namespace
  using DarkRift;
  using System;
  using System.Net.Sockets;
  using System.Timers;
  
  public class Manager : MonoBehaviour {
  
      public Dropdown dropdown;
  
      public Text myText;
  
      public Timer timer;
  
      public string serverSelection = "";
  
      public string serverIP = "";
  
      string text;
 
      // Use this for initialization
      void Start () {
      
      }
      
      // Update is called once per frame
      void Update () {
              myText.text = text;
      }
      public void connectButtonClickHandler()
      {
          print("Connecting to " + serverIP.ToString());
  
          //attempt to connect to the server.
          //Connect to the DarkRift Server using the Ip specified (will hang until connected or timeout)
          try
          {
              DarkRiftAPI.Connect (serverIP);
          } catch(Exception ex)
          {
              print("Cannot connect to. " + serverIP.ToString());
              print("Message: " + ex.Message);
          }
  
          //Setup a receiver so we can create players when told to.
          DarkRiftAPI.onDataDetailed += ReceiveData;
  
          //Tell others that we've entered the game and to instantiate a player object for us.
          if (DarkRiftAPI.isConnected)
          {
              print("Connected to server");
              //Get everyone else to tell us to spawn them a player (this doesn't need the data field so just put whatever)
              //DarkRiftAPI.SendMessageToOthers (TagIndex.Controller, TagIndex.ControllerSubjects.JoinMessage, "hi");
              //Then tell them to spawn us a player! (this time the data is the spawn position)
              //DarkRiftAPI.SendMessageToAll (TagIndex.Controller, TagIndex.ControllerSubjects.SpawnPlayer, new Vector3(0f,0f,0f));
          }
          else
              print("Failed to connect to DarkRift Server!");
  
              //display a message
              myText.text = "Failed to connect to server: " + serverIP.ToString();
  
              //set a timer that makes the message dissapear eventually
              timer = new Timer();
              timer.Interval = 3000;
              timer.AutoReset = false;
              timer.Elapsed += onTimerTick;
              //start the timer
              timer.Start();
  
              //go back to Connect screen
  
      }
      public void onTimerTick(System.Object source, ElapsedEventArgs e)
      {
          print("tick!");
          //empty the error text
          text ="";
      }
      public void onServerSelectionChange()
      {
          print("Changed..!");
  
          if(dropdown.value == 0)
          {
              //Canada selected
              serverSelection = "Canada";
              serverIP = "127.0.0.1";
              print("Canada selected!");
          } else if(dropdown.value == 1)
          {
              //United States selected
              serverSelection = "United States";
              serverIP = "google.com";
              print("United States selected!");
          }
      }
      void ReceiveData (ushort senderID, byte tag, ushort subject, object data)
      {
          print("data received!");
          //When any data is received it will be passed here, 
          //we then need to process it if it's got a tag of 0 and, if 
          //so, create an object. This is where you'd handle most admin 
          //stuff like that.
  
          //Ok, if data has a Controller tag then it's for us
  //        if (tag == TagIndex.Controller)
  //        {
  //            //If a player has joined tell them to give us a player
  ////            if (subject == TagIndex.ControllerSubjects.JoinMessage) 
  ////            {
  ////                //Basically reply to them.
  //////                DarkRiftAPI.SendMessageToID (senderID, TagIndex.Controller, TagIndex.ControllerSubjects.SpawnPlayer, player.position);
  ////            }
  //
  //            //Then if it has a spawn subject we need to spawn a player
  ////            if (subject == TagIndex.ControllerSubjects.SpawnPlayer)
  ////            {
  ////                //Instantiate the player
  ////                //GameObject clone = (GameObject)Instantiate (playerObject, (Vector3)data, Quaternion.identity);
  ////                //Tell the network player who owns it so it tunes into the right updates.
  ////                //clone.GetComponent<NetworkPlayer>().networkID = senderID;
  ////
  ////                //If it's our player being created allow control and set the reference
  //////                if (senderID == DarkRiftAPI.id)
  //////                {
  //////                    //clone.GetComponent<Player>().isControllable = true;
  //////                   // player = clone.transform;
  //////                }
  ////            }
  //        }
      }
  }
actually yes i finally understand what you meant. I got the issue resolved now. I created a variable called message of type String. In update(), i ran the code myText.text = message;
in the timer event handler i changed the code to be the following.
 public void onTimerTick(System.Object source, ElapsedEventArgs e)
     {
         print("tick!");
         //empty the error text
         message = "";
     }
now everything works as expected. thanks.
Your answer
 
 
              koobas.hobune.stream
koobas.hobune.stream 
                       
                
                       
			     
			 
                