2

I am trying to use parse.com service with my unity game. My problem is instantiating objects according to the results received from a query.

For example, when I run the below code;

var queryCurrent = ParseObject.GetQuery("Levels")
.WhereEqualTo("ItemId", "Character")
.WhereEqualTo("Level", "3");

queryCurrent.FirstAsync().ContinueWith(t =>
{
    Character character = ScriptableObject.CreateInstance<Character>();
});

I receive the following error;

CreateInstanceFromType 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.

It seems that this is a general problem and everyone tries to find a workaround by using coroutines. An optimized solution will be appreciated.

Thanks in advance.

emreoktem
  • 2,409
  • 20
  • 36
  • Is this really a parse.com issue or more of just an async issue? The error is pretty explicit that you need to create the objects in the main thread. – TyCobb Jun 26 '14 at 23:21
  • In my case I have issue with parse.com service but in general this should be a general issue with async operations in unity... – emreoktem Jun 27 '14 at 08:56

1 Answers1

3

Use a Coroutine to run things on the main thread. It's documented on the Parse site here: https://parse.com/docs/unity_guide#tasks-coroutines

edit:

Unity provides the notion of a Coroutine for cooperative multitasking, allowing code to be interleaved while all running on the main thread. Tasks and the continuation model are mostly independent of this multitasking mechanism, but are easy to adapt to work within a coroutine. Your coroutine can simply check the IsCompleted property of a task to know whether the asynchronous work has completed, allowing the coroutine to continue where it left off. For example, the following coroutine code saves an object and then waits for a query to return:

public IEnumerator GameOver()
{
    var gameHistory = new ParseObject("GameHistory");
    gameHistory["score"] = score;
    gameHistory["player"] = ParseUser.CurrentUser;

    var saveTask = gameHistory.SaveAsync();
    while (!saveTask.IsCompleted) yield return null;

    // When the coroutine reaches this point, the save will be complete

    var historyQuery = new ParseQuery<ParseObject>("GameHistory")
        .WhereEqualTo("player", ParseUser.CurrentUser)
        .OrderByDescending("createdAt");

    var queryTask = historyQuery.FindAsync();
    while (!queryTask.IsCompleted) yield return null;

    // The task is complete, so we can simply check for its result to get
    // the current player's game history
    var history = queryTask.Result;
}
Fosco
  • 38,138
  • 7
  • 87
  • 101