I have a singleton script to manage the state of a power level. A coroutine within the script regenerates the power back to 100% every second or two if the power level falls below 100%.
From what I can tell you can't use a coroutine on a script unless attached to a GO. I get the error "Coroutine couldn't be started because the the game object 'defaultProperties' is inactive!"
I attached the script to an empty GO but still have the error if it tries to run the coroutine. Is it possible to create a singleton that has coroutines?
As SpikeX already pointed out calling a co-routine recursively might not be a good idea. Using Singletons for global Behaviour and states is a common software architecture. However, you can only start Coroutines from MonoBehaviours and you can't use the "correct" singleton pattern, as you are not supposed to call or change the constructor of a MonoBehaviour.
There are several ways to write a "pseudo-singleton" that is a MonoBehaviour to use with Unity.
That's the easiest way. However you will have to attach this to a GameObject manually in your Scene.
The advanced version will create its own GameObject and attach itself to it as soon as you call it for the first time. This is very convenient and keeps your scene small in the editor. You could also implement something that will remove the object from you scene once it isn't needed anymore (e.g. the coroutines have finished.)
I don't know why you're getting errors, but I see a lot of potential problems with this script. Let me point them out, and we'll hope that one of them was the problem.
answered May 23, 2010 at 08:19 AM
to make the Advanced singleton work,
in the start method, add a call to
then, in the awake method add
when using writing public methods, be sure to add "Instance." to your variables. Also, make sure your public methods are static like this:
Beware that i may have made a few mistakes/type-os, but this is how I have my singleton that uses co-routines setup, and it works as it should. If anybpdy sees a real issue with this, speak up, so we can get this solved once and for all.
BTW, I learned this code from looking at other peoples code, so its my turn to pay it forward.
answered Mar 16, 2011 at 12:10 AM
Full explanation of the new "grid" system is now here ..
Purely for convenience:
In almost all projects: it will be the case that you will have an empty game object attached on your opening scene, for clarity let's call it "holdAll".
"holdAll" is persistent throughout the game.
Attached to that, you will have many files such as Shopping.js, Analytics.js, Calculations.js .. etc etc
Each of those uses coroutines. So they really are best as "normal" scripts attached to an game object.
Again, it's inevitable that almost every Unity game has an empty game object ("holdAll") which is persistent throughout the whole game, and you use those various
I've never seen a Unity project that does not have that.
So, this is all great and normal. But, each time you want to use a routine from shopping.js, you need to make a local variable which, annoyingly, you have to hook to shopping.js on holdAll.
Of course, it's much easier to just call ordinary static libraries, like when you use Mathf or the like.
Is there a solution?
Yes, here's what I do. Make a tiny little class called say "grid":
then from anywhere at all in your project,
with no further effort,
you can just write
and so on. Same for all the others (Shopping.js, Analytics.js, Calculations.js etc etc)
I want the convenience of just being able to say
anywhere in the project WITHOUT needing an annoying hooked-up local variable "shopit" which leads to holdAll-Shopping.js.
But in my opinion there's just no really good, bulletproof, way to make a static/singleton/etc, where it's a "normal" coroutine-based Unity object.
So ... for me, this seems to answer all those needs. The only downside is effectively one extra "." when you type grid.shopping.
Seems to work ok ?