Boolean-triggered mouse-down won't work

Hey, guys, sorry for what’s probably a noob question.

I’m just learning to code in Unity with .js and I’ve had to build a script for an example. It’s supposed to do the following:

  • There are three seeds hovering just above the ground. When the player clicks on them, they translate down and become embedded in the ground, thus being “planted”.
  • They then get watered and “grow” to a larger sapling. This is done (very scruffily) by clicking on the nearby watering can, then clicking the seed. A boolean (hasWater) is triggered by clicking on thje can, which then allows the seed to do its other OnMouseDown function. I’ve only attached this to the first seed so far, for testing reasons, but the gist of it is, the seed should then translate way down out of sight to make room for the model of the sapling. I know I should probably use “Destroy” or something instead, but I can see no reason why it wouldn’t at least work, however inefficiently. I also haven’t made the sapling model yet, because I want to make sure I can get rid of the seed properly first.

So I click the seeds, they plant. I click the watering can, it makes its sloshing noise. I click the seed that’s supposed to be watered and vanished. Not a sausage. Can anyone look through this code and tell me why?

private var seedIsPlanted : boolean = false;
private var hasWater : boolean = false;
private var currentSeed : GameObject;
private var lastSeed : GameObject;


var dirtSound : AudioClip;
var waterSound : AudioClip;
//var plantGrowSound : AudioClip;


function Update () {
	
}

function OnMouseDown() {

	if(gameObject.tag == "wateringcan"  hasWater == false) {
		audio.PlayOneShot(waterSound);
		hasWater = true;
		}
	else if(gameObject.tag == "Seed1"  seedIsPlanted == false  hasWater == false) {
		transform.Translate(0,-1,0);
		audio.PlayOneShot(dirtSound);
		seedIsPlanted = true;
		}
	else if(gameObject.tag == "Seed2"  seedIsPlanted == false) {
		transform.Translate(0,-1,0);
		audio.PlayOneShot(dirtSound);
		seedIsPlanted = true;
		}
	else if(gameObject.tag == "Seed3"  seedIsPlanted == false) {
		transform.Translate(0,-1,0);
		audio.PlayOneShot(dirtSound);
		seedIsPlanted = true;
		}
	else if(gameObject.tag == "Seed1"  hasWater == true) {
		transform.Translate(0,-10,0);
		Debug.Log("please go underground, you hovering wretch");
		
		}

	
	
	}

Is it something to do with how many else-ifs I’ve got lumped into the one OnMouseDown?

I can’t answer you, but I can tell you that your code is WAY too complicated. You are making a too intensive use of if else.

You have three seeds.

You have a watering can.

Those are differents objects. You should divide your script into two scripts.

Do something like :

// Seed.js script

// VARIABLES
public var dirtSound : AudioClip;

private var seedIsPlanted : boolean = false;

public var wateringCan : WateringCan;

// EVENTS
function OnMouseDown()
{
	if (seedIsPlanted == false)
	{
		transform.Translate(0,-1,0);
		audio.PlayOneShot(dirtSound);
		seedIsPlanted = true;
	}
	else if(wateringCan.hasWater == true)
	{
		transform.Translate(0,-10,0);
		Debug.Log("please go underground, you hovering wretch");
	}
}
// WateringCan.js

// VARIABLES
public var waterSound : AudioClip;

public var hasWater : boolean = false;

// EVENTS
function OnMouseDown ()
{
	hasWater = !hasWater;
	if (hasWater == true)
		audio.PlayOneShot (waterSound);
}

Wow, that is so much better. Thanks a bunch!

Unfortunately, I’ve plugged the code in and it still plants, still makes the sloshing noise, but on the click that should push the seed underground, it says the following:
NullReferenceException: Object reference not set to an instance of an object
Seed.OnMouseDown () (at Assets\MyScripts\Seed.js:19)

else if(wateringCan.hasWater == true)

In the Inspector, for each seed, did you put the watering can in that variable field ?

Derp! No, I didn’t. I have now, and it works like a dream.

Only one problem remains, though: I think I must be doing something really wrong with my booleans and ifs, because I can’t get them to work in a way that my limited mind insists is logical.

I wanted the player to have to click the watering can again to water each individual seed, and for the watering can to be able to slosh only once between waterings, and not be able to slosh on repeated clicks, so I altered the code to this:

// Seed.js script

// VARIABLES
public var dirtSound : AudioClip;

private var seedIsPlanted : boolean = false;

public var wateringCan : WateringCan;

// EVENTS
function OnMouseDown()
{
   if (seedIsPlanted == false)
   {
      transform.Translate(0,-1,0);
      audio.PlayOneShot(dirtSound);
      seedIsPlanted = true;
   }
   else if(wateringCan.hasWater == true)
   {
      transform.Translate(0,-10,0);
      Debug.Log("please go underground, you hovering wretch");
	  wateringCan.hasWater = false;
   }
}
// WateringCan.js

// VARIABLES
public var waterSound : AudioClip;
public var hasWater : boolean = false;
public var wateringCan : WateringCan;

// EVENTS
function OnMouseDown ()
{
  if (wateringCan.hasWater == false)
		wateringCan.hasWater = true;
		audio.PlayOneShot (waterSound);
}

Now, the player can’t just click the watering can once and then click all the seeds underground; they have to click can, seed, can, seed, can, seed. That works, and that’s the really important part. But despite the conditions I put on the watering can - if (wateringCan.hasWater == false) - it keeps sloshing on repeated clicks, and I can’t see why. I always seem to run into this problem with booleans. What did I screw up?

Your reworking of my scripts helped me out a lot. Thank you very much. :smile:

I was going to bed, thinking everything was ok, but I was too optimistic, heh. :slight_smile:

// WateringCan.js

// VARIABLES
public var waterSound : AudioClip;
public var hasWater : boolean = false;

// EVENTS
function OnMouseDown ()
{
	if (hasWater == false)
	{
		hasWater = true;
		audio.PlayOneShot (waterSound);
	}
}