Change Variable(boolean) in Another Script (SOLVED)

I have 2 scripts running in my game, one attached to a transform (spawnHandler) called “RandomSpawnRandomLocation”

#pragma strict
 
  var spawnPoint : Transform[]; // Create list of possible spawn locations
  var wepType : GameObject[]; // Creat list of possible weapons to be spawned
  var wepPresent : boolean = false;
 
  function Start()
  {
   SpawnWeapons(); //Run SpawnWeapons coroutine
  }
 
  function Update()
  {
   if(wepPresent == false) //Check to see if weapon is present
   {
   SpawnWeapons(); //If no weapon is present run SpawnWeapons coroutine
   }
  }
 
  function SpawnWeapons() //Spawns a random weapon at one of possible spawn locations
  {
  var randomLoc : int = Random.Range(0,4); //Pick random number between 1 and 4
  var randomWep : int = Random.Range(0,4); //Pick random number between 1 and 4
 
  Instantiate(wepType[randomWep], spawnPoint[randomLoc].position, spawnPoint[randomLoc].rotation);
  //Pick random weapon depending on which number was generated by 'randomWep'
  //Spawn weapon at location depending on which number was generated by 'randomLoc'
 
  wepPresent = true;
  }

The other is a simple self destruct script attached to the gameObjects/prefabs that get spawned - “DestroySelfOnContact”
(the objects this script is attached to are prefabs and get spawned/destroyed multiple times)

#pragma strict
 
  function OnTriggerEnter()
  {
  Destroy (gameObject);
  }

How do I get the DestroySelfOnContact script to change the ‘wepPresent’ variable on the RandomSpawnRandomLocation script ?
Would I be better off having the destroy script attached to my player object as that is always present in the scene ?
???

var wepPresent : boolean = false; Has now been changed to -

public var wepPresent : boolean = false;

And my destroySelfOnContact script now is -

#pragma strict

  public var getSpawnHandler :  GameObject;

  private var randomWeaponRandomLocation : RandomWeaponRandomLocation;



  function Awake ()
  {
  randomWeaponRandomLocation = getSpawnHandler.GetComponent(RandomWeaponRandomLocation);
  }


  function OnTriggerEnter()
  {
  Destroy (gameObject);
  randomWeaponRandomLocation.wepPresent = false;
  }

I’m getting no compile errors, but nothing is actually happening.
Shouldn’t this now be affecting/changing the variable on the ‘other’ script
???

Anybody?

Try something like

var newWeapon = Instantiate(wepType[randomWep], spawnPoint[randomLoc].position, spawnPoint[randomLoc].rotation);

This lets you access the specific weapon you instantiated. Use GetComponent to access the destroySelfOnContact script that the weapon has, like this:

newWeapon.GetComponent(destroySelfOnContact);

On you destroySelfOnContact script, have a bool that starts as false, in this example we’ll use a bool called ‘destroyed’. We can set this to true just before we tell it to destroy itself, and read that from the RandomSpawnRandomLocation script. This gives you something like this:

RandomSpawnRandomLocation

#pragma strict

var spawnPoint : Transform[]; // Create list of possible spawn locations
var wepType : GameObject[]; // Creat list of possible weapons to be spawned
var wepPresent : boolean = false;

function Start()
{
    SpawnWeapons(); //Run SpawnWeapons coroutine
}

function Update()
{
    if(wepPresent == false) //Check to see if weapon is present
    {
        SpawnWeapons(); //If no weapon is present run SpawnWeapons coroutine
    }
}

function SpawnWeapons() //Spawns a random weapon at one of possible spawn locations
{
    var randomLoc : int = Random.Range(0,4); //Pick random number between 1 and 4
    var randomWep : int = Random.Range(0,4); //Pick random number between 1 and 4

    var newWeapon = Instantiate(wepType[randomWep], spawnPoint[randomLoc].position, spawnPoint[randomLoc].rotation);
    //Pick random weapon depending on which number was generated by 'randomWep'
    //Spawn weapon at location depending on which number was generated by 'randomLoc'

    wepPresent = true;

    if(newWeapon.GetComponent(destroySelfOnContact).destroyed = true)
    {
        wepPresent = false;
    }
}

destroySelfOnContact

#pragma strict

public var getSpawnHandler :  GameObject;
var destroyed = false;

private var randomWeaponRandomLocation : RandomWeaponRandomLocation;



function Awake ()
{
    randomWeaponRandomLocation = getSpawnHandler.GetComponent(RandomWeaponRandomLocation);
}


function OnTriggerEnter()
{
    destroyed = true;
    Destroy (gameObject);
    randomWeaponRandomLocation.wepPresent = false;
}

As a warning, this is 4am for me so the script is untested. Let me know if you run into problems and I’ll be happy to help out. =)

1 Like

You should get some sleep dude…lol

Anyway, same as before… not getting any errors but once I destroy the first object(weapon) it doesn’t then spawn a new weapon

???

Sleep is for the weak. =P
Besides, I have a non standard schedule.

Anywho, I messed about with it a bit. I’m assuming you want to use a prefab for the object the second script is attached to, in which case when it spawns it won’t have a reference to the first script. To get around this, we set the ‘getSpawnHandler’ variable from the manager script (RandomSpawnRandomLocation).
To do this though, we need to move stuff out of the Awake function and into the Start function. For what I see here so far this won’t make a difference except that we can assign the variables of the object when it’s first instantiated, instead of running into errors. If you do need that stuff in the Awake function, let me know.
We also want to move ‘randomWeaponRandomLocation.wepPresent = false;’ above the Destroy command, otherwise it won’t get called.
You also called the first script two different things, so I decided to go with one of them. Feel free to change it if I was wrong. =P

This leaves us with this:
RandomSpawnRandomLocation

#pragma strict

var spawnPoint : Transform[]; // Create list of possible spawn locations
var wepType : GameObject[]; // Creat list of possible weapons to be spawned
var wepPresent : boolean = false;

function Start()
{
    SpawnWeapons(); //Run SpawnWeapons coroutine
}

function Update()
{
    if(wepPresent == false) //Check to see if weapon is present
    {
        SpawnWeapons(); //If no weapon is present run SpawnWeapons coroutine
    }
}

function SpawnWeapons() //Spawns a random weapon at one of possible spawn locations
{
    var randomLoc : int = Random.Range(0,spawnPoint.length); //Pick random number between the min and max values of the array containing the spawn locations.
    var randomWep : int = Random.Range(0,wepType.length); //Pick random number between the min and max of the array containing the weapon types.

    var newWeapon = Instantiate(wepType[randomWep], spawnPoint[randomLoc].position, spawnPoint[randomLoc].rotation);
    newWeapon.GetComponent(destroySelfOnContact).getSpawnHandler = this.gameObject;
    //Pick random weapon depending on which number was generated by 'randomWep'
    //Spawn weapon at location depending on which number was generated by 'randomLoc'
 
    wepPresent = true;
 
    if(newWeapon.GetComponent(destroySelfOnContact).destroyed == true)
    {
        wepPresent = false;
    }
}

destroySelfOnCollision

#pragma strict

public var getSpawnHandler : GameObject;
var destroyed = false;

private var randomWeaponRandomLocation : RandomSpawnRandomLocation;

function Start()
{
    randomWeaponRandomLocation = getSpawnHandler.GetComponent(RandomSpawnRandomLocation);
}

function OnTriggerEnter()
{
    destroyed = true;
    randomWeaponRandomLocation.wepPresent = false;
    Destroy (gameObject);
}

You also need to make sure that whatever the second script is attached to has a rigidbody. You can turn the gravity off and mess with whatever other values you like.
This has now been tested, so let me know of any further issues. =)

1 Like

There were a couple of errors, 2 were capitalisation (no big deal) the other was that ‘RandomSpawnRandomLocation’ should have actually been ‘RandomWeaponRandomLocation’. We’ll put that down to a mix of my bad explaining and you’re lack of sleep…lol
After that it ran like a dream, does exactly what I wanted it to.
You my friend are a lifesaver and a gentleman ! !

A couple of questions though…
I understand what I’d done wrong by putting Destroy (gameObject) before the Boolean (can’t change it if its already been destroyed) Doh !

But you also changed these two lines -

var randomLoc : int = Random.Range(0,spawnPoint.length); //Pick random number between the min and max values of the array containing the spawn locations.
var randomWep : int = Random.Range(0,wepType.length); //Pick random number between the min and max of the array containing the weapon types.

Why did your way work? and what was it that made my way not work ? I can see the differences, but without actually understanding them I won’t learn from my mistake?

Many, many thanks

:slight_smile:

EDIT - Just realised I haven’t attached any rigidbody component to any of the weapon prefabs and it still works fine? Was that just a personal preference thing for you or should that have had some impact on the game/scripts ?

The reason it wasn’t destroying itself is because it wasn’t getting triggered. This is why I told you to add a rigidbody, so that the collision happens, triggering the OnTriggerEnter function.
I also changed it a little so that you could make it a prefab. If you made it a prefab as it was, it wouldn’t store the getSpawnHandler reference, meaning you’d have to use Find to get it every time the prefab was instantiated. Instead, the script making them passes a reference of itself to the value just after instantiation. I had to move all of that out of Awake() and into Start() though, because Awake() happens to early for this to work.

The two lines of code you quoted there didn’t actually have anything to do with why your script wasn’t working, but to future proof them against changing how many weapons or spawn locations you wanted to add. With just a number written there, you’d have to change the number to match the length of the relevant array every time. This way it picks between 0 (the first in the array) and however many you have.