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

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?

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.

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.

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.

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.

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.

No

Welp, thanks for the help anyways.

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.