Ok, let’s take a different approach here. Instead trying to find what could possibly cause such an error, let us rewrite all of your classes, but this time properly.
Namely, the way you are using your classes. Both LetterA, LetterR, LetterC are using practically the same code. After all, they are letters. The way classes work is that they are meant to have multiple instances during the lifetime of the app. As soon as you create LetterA, you assign it to a global variable GameInstance.
Sure, it is convenient, but if you create a level with words C A R C H O A L, you have two instances of A and two of C, automatically overwriting your previous GameInstance with the second. Hence, the code breaks and you can’t reuse the same code for different letters.
Let’s create a simple class called PickableItem, which will have all the functionality required for this game to work. Sure, we are using Letters in this game, but giving it a generic name will allow us to use it in, perhaps, another game. After all, in Unity Component based scripting it is better to think what are GameObjects composed of, instead what an GameObject is.
public class PickableItem : MonoBehaviour
{
public GameObject hiddenObject;
public string requiredTag;
bool m_pickedFlag = false;
public bool IsPickedUp
{
set
{
m_pickedFlag = value;
hiddenObject.SetActive(m_pickedFlag);
}
get
{
return m_pickedFlag;
}
}
void OnTriggerEnter2D(Collider2D collisionObject)
{
if (IsPickedUp)
return;
if (collisionObject.tag == requiredTag)
{
IsPickedUp = true;
}
}
}
And a main game object script that will behave as a game manager.
using System.Collections.Generic;
public class GameManager : MonoBehaviour
{
public List<PickableItem> items;
public int nextLevel;
void Update()
{
int result = 0;
for (int i = 0; i < items.Count; i++)
{
if (items[i].IsPickedUp)
result++;
}
if (result == items.Count)
PrepareVictoryScene();
}
void PrepareVictoryScene()
{
Application.LoadLevel(nextLevel);
}
}
Okay, let us review the code above. GameManager will behave as a singleton, hence just create one empty game object and assign it a GameManager script.
Now create your letter game objects. Now I’m kinda saying things blindly since you haven’t provided how you really set up your classes (you had LetterA and Letter_A classes with different functionality so I can’t help myself), but I would do the workflow like this:
Create all your letters on the scene and give them PickableItem script. Assign the required tag in the inspector. Add your hidden gameObjects as a child of the letter and set it as Deactivated. Also link it in the inspector don’t forget. I assume the hidden gameObject looks differently from the original letter, so the player can see it was picked up.
Once you created all of your letters, assign them to your GameManager items list in the inspector. That should be it! Once you start the program, GameManager will enumerate all your PickableItems and once they all have IsPickedUp set to true, you should proceed to the victory screen.
I hope this wall of text helps you a bit. Singletons are okay sometimes to use, GameManager could be a singleton, but then again it could create a bad habit of linking your singleton reference to many scripts, effectively making them more dependable on the GameManager. Then you couldn’t take your PickableItem script and put it in another project, you would have to refactor it. By keeping your PickableItem unaware of any game logic, they become more reusable and that is the point of Unity programming, creating small chunks of code that can be used on many different game object.
Also, I would recommend you to choose wisely class names. By creating LetterA and Letter_A, it will confuse your fellow programmers that work together on same project, because you cannot understand what the class does from the naming. Having a PickableItem, I’m sure every newcomer can immediately understand what this class is used for.
Good luck with your project, and sorry for the wall of text!