Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Destroy can only be called from the main thread. <-Useless error

Discussion in 'Editor & General Support' started by 0x0000, Aug 15, 2014.

  1. 0x0000

    0x0000

    Joined:
    Apr 21, 2014
    Posts:
    5
    Hey, I'm having a problem with Unity where there is not enough information in an error to debug the problem. Apparently I am calling GameObject.Destroy() from a constructor or something of that sort, and unity does not like that at all. Unfortunately, I have hundreds of scripts, which means walking through each script manually is not feasible. Even if I only check the constructors in my code, there are still too many places the error could be coming from. On top of that, I'm not even 100% sure the problem even IS a constructor.

    Is there a better way to go about debugging this problem than scanning every file/ctor?
     
  2. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    The message is very precise. You are calling destroy from another thread. You most likely know what kind of functionality is executed outside of the main thread, which should help you a lot to isolate the issue. It doesn't necessarily happen within a constructor if you just consider the error message.
     
  3. Cygon4

    Cygon4

    Joined:
    Sep 17, 2012
    Posts:
    382
    Unity error messages also provide you with a call stack, telling you exactly which of your methods is calling the GameObject.Destroy() in question and which method is calling that method and so on all the way back to the original Unity hook or thread method you're executing.
     
  4. Graph

    Graph

    Joined:
    Jun 8, 2014
    Posts:
    153
    instead of calling it directly you could put it as an Action into a queue then on update dequeue and execute the actions until none are left and you'll have solved it.
     
  5. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    That's would just be a workaround for a bad design. Unless the design decision is to make it like that because no better solution exists.
     
  6. 0x0000

    0x0000

    Joined:
    Apr 21, 2014
    Posts:
    5
    Thanks for all the replies! The problem is that this specific error is not providing me with a call stack or any other useful information, merely that the error occurred. Again, I can't be sure where this error is occurring since we have several people working on a fairly large project, and many many files that could possibly be the culprit. My question was not how to solve the problem, since there are many solutions, but rather I would like to know if there is a better way to FIND it.
     
  7. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    No
     
  8. 0x0000

    0x0000

    Joined:
    Apr 21, 2014
    Posts:
    5
    Welp, thanks for the help anyways.
     
  9. Rs

    Rs

    Joined:
    Aug 14, 2012
    Posts:
    74
    The last time I had this it was due to a ComputeShader looking for a ComputeBuffer that was declared in the Start function. When Start finished, the ComputeBuffer variable in the script was obviously destroyed but the binding with the ComputeShader was still there.
    The code was doing this in the Start()

    ComputeBuffer buffer = new ComputeBuffer(data.Length, 76);

    The complete error was this:

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


    This case is easily solved by moving the declaration of the ComputeBuffer so it's a class filed, which makes sense as the ComputeBuffer should stay there as long as it's bound to the ComputeShader. So declare like

    ComputeBuffer buffer;

    and then in the Start do

    buffer = new ComputeBuffer(data.Length, 76);

    This solves this particular case but if you get this error then any scripts that manipulate ComputeShaders are among the possible causes.
     
    Last edited: Jan 26, 2016