lock and key mechanic: how to use variables across scripts

I’m trying to do something relatively simple but getting stuck. just wondering if I could get a little help. I’m pretty new to scripting in unity and don’t come from a coding background so I’ll try and show my current workings.

I have 2 game objects. One is a card that the player collects which has this script (CollectedCard.js) attached:

var card : GameObject;
static var cardCollected: boolean;

function OnTriggerEnter() {
cardCollected = true;
card.active = false;
}

I also have an empty gameObject with a timer script attached that (amongst other things) counts down and when the timer reaches zero performs this check:

static var Collected = CollectedCard.cardCollected;
var success: String ; //level to load on success
var fail: String ; //level to load on fail

if (restSeconds == 0) 
		if (Collected) 
        Application.LoadLevel(success);
		else
        Application.LoadLevel(fail);   

What I’m trying to do is; once the player has collected the card (detected in one script) set a bool to true in the other so that it loads a specific “success” scene, or else load a “fail” scene. What’s happening is that it always loads the “fail” scene.

Now I’m firstly not too hot on my syntax anyway, but I’m not even sure if I’m doing this correctly so any pointers would be greatly appreciated. I understand it’s pretty basic, but I couldn’t quite find what I was looking for elsewhere.

Sorted it! I removed the static var Collected = CollectedCard.cardCollected; and then added the reference to the other script directly into the function, so:

if (restSeconds == 0) 
	if (CollectedCard.cardCollected)
    Application.LoadLevel(success);
	else
    Application.LoadLevel(fail) ;

Took a bit of jiggling about semi-colons and “squiggly brackets”. I guess I really ought to learn the logic behind the syntax :slight_smile:

Your syntax is fine, but your logic is a little off.

It seems that you are assuming that the line

static var Collected = CollectedCard.cardCollected;

causes ‘Collected’ to always refer to CollectedCard like a reference type. Of course, booleans are a value type- which means that at the moment that line is declared, Collected will be set to whatever CollectedCard.cardCollected was at that moment, and there is no further connection between the two, and when you use it in your ‘if’ statement it will still hold the value that CollectedCard.cardCollected had when it was declared, which is of course false.

If you remove the variable entirely, and just use

if(CollectedCard.cardCollected)

it will remove this problem entirely.

Of course, using static variables is prone to problems, especially if you are planning to have the ability to restart the level. If you reset the level at runtime, the variable ‘CollectedCard.cardCollected’ won’t get reset automatically, since it will remember the value from the previous playthrough. If you instead make it an instance variable, and then keep a reference to that instance in your counter script, it won’t have any of the same problems.

var card : GameObject;
var cardCollected: boolean;

function OnTriggerEnter() {
    cardCollected = true;
    card.active = false;
}

var cardCollector : CollectedCard;

if(cardCollector.cardCollected)
{
    // success!
} else {
    // fail.
}

In your second script, just drag the gameobject with the CollectedCard component attached to it onto the ‘cardCollector’ variable in the inspector, and it will work fine.