Search code examples
multithreadingunity-game-enginegameobject

Untiy | Find can only be called from the main thread


I want to move the gameobject named "Capsule" when i press the button that i made. The json data is sent to server at this moment. I'm just trying to test that the button can control the gameobject. This is the script I've done from now on and the error is occurred now. Please give me some idea to fix this. All i want to do is control the gambject named "Capsule" when i press the button".

using UnityEngine;
using System.Collections;
using SimpleJSON;
using UXLib;
using UXLib.Base;
using System.Collections.Generic;

public class Main : MonoBehaviour {

public int Speed;
PadController padController;
public float time;

void Start () {
    padController = PadController.Instance;
}

public void init(){

}

// Update is called once per frame
void Update () {
}

public void OnTouchStart(string name, string time){
    //ObjectMoveStart();
    Debug.Log ("TouchStart -> name : " + name + ", time : " + time);
}

public void OnTouchEnd(string name, string time){
    //ObjectMoveEnd();
    Debug.Log ("TouchEnd -> name : " + name + ", time : " + time);
}

public void ObjectMoveStart(){
    GameObject cap = GameObject.Find("Capsule");
    cap.transform.Translate(Vector3.left * 10 * 10.0f);
}
public void ObjectMoveEnd(){
    GameObject cap = GameObject.Find("Capsule");
    cap.transform.Translate(Vector3.left * 0 * 0.0f);
}


void OnGUI() {

    GUI.color = Color.white; 
    GUI.skin.label.fontSize = 30;
    GUI.skin.button.fontSize = 30;

    //GUI.Label(new Rect(20, 40, 1600, 800), ">"+logString);

    if (GUI.Button (new Rect (10, 0, 80, 40), "Type1")) {
        // padType1 선택  
        padController.Init (PadController.PAD_TYPE1);
        //Arrow Buttons
        padController.SetPosition (0, -3.5f, -2.5f);   
        padController.SetPosition (1, -6.0f, 0.0f);
        padController.SetPosition (2, -1.0f, 0.0f);
        padController.SetPosition (3, -3.5f, 2.5f);
        padController.SetVisible (0, true);
        padController.SetVisible (1, true);
        padController.SetVisible (2, true);
        padController.SetVisible (3, true);
        //Alphabet Buttons 
        padController.SetPosition (4, 4.5f, 1.5f);
        padController.SetPosition (5, 3.0f, 0.0f);
        padController.SetPosition (6, 6.0f, 0.0f);
        padController.SetPosition (7, 4.5f, -1.5f);
        padController.SetVisible (4, true);
        padController.SetVisible (5, true);
        padController.SetVisible (6, true);
        padController.SetVisible (7, true);

        padController.OnTouchStart += OnTouchStart;
        padController.OnTouchEnd += OnTouchEnd;
        //padController.OnMoveStart += ObjectMoveStart;
        //padController.OnMoveEnd += ObjectMoveEnd;
        padController.Load ();
    } 
}
}

This is the error occurred.

Find can only be called from the main thread. Constructors and field initializers will be executed from the loading thread when loading a scene. Don't use this function in the constructor or field initializers, instead move initialization code to the Awake or Start function.


Solution

  • Move your GameObject.Find calls, to Start()

    Since, you're calling the Same GameObject "Capsule" why don't you just Call it once in the Start and Reference it.

    Outside all the Methods declare.

    GameObject cap;
    void Start(){
     cap = GameObject.Find("Capsule");
    }
    

    then remove all of your other GameObject.Find. It is irrelevant to Find the same object everytime.

    GameObject.Find is the slowest Call function in UnityEngine. Consider referencing the GameObject in the Inspector by dragging the GameObject instead.