I’m coding a simple match 3 game, but I’m stuck with having the logic of the game and the simple movement of the coins work at the same time.
I was suggested to use the singleton pattern. Everything works fine, but the coroutine is not triggering. I have the following code estructure:
in base_coin.js
CheckActiva.GetInstance().Checkeo();
in CheckActiva.js (the singleton), the following code:
class CheckActiva
{
private static var Instance : CheckActiva;
public static function GetInstance() : CheckActiva
{
if (Instance == null)
Instance = new CheckActiva();
return Instance;
}
var state : boolean ;
private function CheckActiva()
{
state=false;
}
function GetState() : boolean
{
return state;
}
function Checkeo(){
//this function checks if the coin meets the conditions to be activated. If so, activates function CheckMatch
CheckMatch ();
}
function CheckMatch (){
//this function checks if there are 3 coins in a row, if so activates Matchthree
Matchthree ();
}
function Matchthree (){
//this function does a number of things such as changing 3 smaller coins into 1 big one, and starts function Animate, a coroutine to smoothly move the coins into place
yield Animate();
}
function Animate (): IEnumerator {
Debug.Log("Inside Animate");
// this function never triggers, it doesn't print anything, it is not triggering because of the 'yield' keyword in Matchthree
}
}//end of class CheckActiva
Sorry, I’m a newby and need some more explanation… The manual says ‘Using Javascript every script automatically derives from MonoBehaviour.’ What else should I do for this to work?? Or is there a different structure that I could use?
Thanks again!
By automatic they mean “no class declaration”. You’ve declared the class at the top of your CheckActiva file. Either remove that or add “extends MonoBehaviour” and attach it to a GameObject in your world. (You’ll also have to remove the constructor in your static get instance - there are a bunch of MonoBehaviour “singletons” floating around if you search for them - as much as I disagree with their implementation )
Well, I’m still stuck here so I really need some help…
I went through all the ‘singleton’ posts in the forum and could’nt find an example in javascript of a Monobehavior singleton. I tried to translate and mix some code, but I’m not a coder, so I guess the problem is I’m messing with the syntax… I get a ‘Nullreference exception’ at this line in base_coin.js:
CheckActiva.Instance().Checkeo();
The singleton code in Checkactiva.js:
public class CheckActiva extends MonoBehaviour
{
private static var instance : CheckActiva;
public static function Instance() : CheckActiva
{
if (Instance == null)
return instance;
}
function Awake() {
instance = this;
}
}
Your Instance() function doesn’t make any sense. Instance is a function but you’re trying to treat it like an object. The null check isn’t actually necessary because you assign instance in Awake.
Did you add CheckActiva to a GameObject?
Are you sure you want a Singleton? Using one “because someone said to” isn’t a great reason.
Hi,
thanks a lot for your help.
Yes, I added CheckActiva to an empty GameObject in the scene. The reason I need this script to be a singleton is that I want to run a coroutine to fire a smooth animation. The animation triggers when conditions in other object’s scripts are met, so I need an access between scripts. I would use static functions, but then I couldn’t run coroutines on them…I’m open to any other alternatives that allow me to do that: access a script from another, then trigger a smooth animation.
public class ImpactManager : MonoBehaviour
{
private static ImpactManager s_instance;
public static ImpactManager Instance
{
get { return s_instance; }
private set { s_instance = value; }
}
void Awake()
{
if (Instance != null)
{
Destroy(gameObject);
}
else
{
Instance = this;
}
}
}
This is how we use each of our “Managers” (What we call Singletons).
In yours I notice that you check to see if its null then return if it is? That doesn’t really make sense.
Of course… is the same problem I have with all the other working examples I find here in the forum, they are in C# and as I said, I’m not a coder, and I’m not able to convert the C# code into Javascript… Can anyone point me to an example in JS? What are the equivalents of the ‘get’ and ‘set’ operators? Is it even possible to write a singleton in Unity’s Javascript? Thanks for your time, guys!
Sorry, I already tried that and it still gives the ‘nullreference exception’ error… This is the cleaned code:
public class CheckActiva extends MonoBehaviour
{
private static var instance : CheckActiva;
public static function Instance() : CheckActiva {
return instance;
}
function Awake() {
instance = this;
}
}
He’s probably just calling the Instance in the awake method somewhere else. If you want to use a Singleton you should place any uses of it in the Start() so the Singleton has time to initialize itself.
the script where the class is defined is attached to an empty game object in the scene. The only place where I am attempting to get the instance of the class is in the Start() function in base_coin.js.
I noticed in the inspector, though, that the script has the following warning: ‘The script cannot be loaded. Please fix any compile errors and assign a valid script’. There are no compile errors, though.
If I delete the contents of the script entirely, the warning is still there. I tried erasing the script, creating a new script component, pasting only the header of the class, and the warning fires again. So, it seems that the problem is with the declaration of the class itself:
public class CheckActiva extends MonoBehaviour {
}
Both scripts (base_coin.js and CheckActiva.js) are in the same folder (in ‘Assets’). I rebuilt the project, so that the scripts where re-linked, but same result. I also tried changing the class name, just in case, and looked for duplicate scripts in the folder (there weren’t).
Can it be a Unity bug?? What can I do to debug this??
Ok, I finally got it working
I don’t really know what the problem was…
As I said, I deleted the original CheckActiva.js script and created a new one, this one named ‘Singleton.js’. The error given by the initialization of the class was due to my mistake: I named the class differently than the script. Once I fixed this, I started copying all the contents of the old CheckActiva.js script into Singleton.js and now it works. So, eventually the code was ok, but something in the file was corrupted or whatever (??).
I just wanted to thank you all, guys, you’ve been really helpful, without your help I would have spend ages trying to narrow the possibilities…!