DoubleCode
DoubleCode

Reputation: 195

How to access a variable from another script in another gameobject through GetComponent?

I've searched around and I just can't get this to work. I think I just don't know the proper syntax, or just doesn't quite grasp the context.

I have a BombDrop script that holds a public int. I got this to work with public static, but Someone said that that is a really bad programming habit and that I should learn encapsulation. Here is what I wrote:

BombDrop script:

 <!-- language: c# -->

 public class BombDrop : MonoBehaviour {

 public GameObject BombPrefab;

 //Bombs that the player can drop
 public int maxBombs = 1;


 // Update is called once per frame
 void Update () {

 if (Input.GetKeyDown(KeyCode.Space)){

         if(maxBombs > 0){
         DropBomb();

         //telling in console current bombs
         Debug.Log("maxBombs = " + maxBombs);
         }
   }


 }    

 void DropBomb(){

     // remove one bomb from the current maxBombs
     maxBombs -= 1;

     // spawn bomb prefab
     Vector2 pos = transform.position;
     pos.x = Mathf.Round(pos.x);
     pos.y = Mathf.Round(pos.y);
     Instantiate(BombPrefab, pos, Quaternion.identity);

 }
}

So I want the Bomb script that's attached to the prefabgameobject Bombprefab to access the maxBombs integer in BombDrop, so that when the bomb is destroyed it adds + one to maxBombs in BombDrop.

And this is the Bomb script that needs the reference.

 public class Bomb : MonoBehaviour {
 // Time after which the bomb explodes
 float time = 3.0f;

 // Explosion Prefab
 public GameObject explosion;

 BoxCollider2D collider;

 private BombDrop BombDropScript;




 void Awake (){

     BombDropScript = GetComponent<BombDrop> ();
 }

 void Start () {

     collider = gameObject.GetComponent<BoxCollider2D> ();

     // Call the Explode function after a few seconds
     Invoke("Explode", time);

 }

 void OnTriggerExit2D(Collider2D other){

     collider.isTrigger = false;
 }

 void Explode() {
     // Remove Bomb from game
     Destroy(gameObject);

     // When bomb is destroyed add 1 to the max 
     // number of bombs you can drop simultaneously .
     BombDropScript.maxBombs += 1;

     // Spawn Explosion
     Instantiate(explosion,
                 transform.position,
                 Quaternion.identity);

In the documentation it says that it should be something like

BombDropScript = otherGameObject.GetComponent<BombDrop>();

But that doesn't work. Maybe I just don't understand the syntax here. Is it suppose to say otherGameObject? Cause that doesn't do anything. I still get the error : "Object reference not set do an instance of an object" on my BombDropScript.maxBombs down in the explode()

Upvotes: 18

Views: 93355

Answers (3)

Omdevsinh Gohil
Omdevsinh Gohil

Reputation: 155

Can Use this :

entBombDropScript.maxBombs += 1;

Before :

Destroy(gameObject);

I just want to say that you can increase the maxBombs value before Destroying the game object. it is necessary because, if you destroy game object first and then increases the value so at that time the reference of your script BombDropScript will be gone and you can not modify the value's in it.

Upvotes: 0

axwcode
axwcode

Reputation: 7824

You need to find the GameObject that contains the script Component that you plan to get a reference to. Make sure the GameObject is already in the scene, or Find will return null.

 GameObject g = GameObject.Find("GameObject Name");

Then you can grab the script:

 BombDrop bScript = g.GetComponent<BombDrop>();

Then you can access the variables and functions of the Script.

 bScript.foo();

I just realized that I answered a very similar question the other day, check here: Don't know how to get enemy's health


I'll expand a bit on your question since I already answered it.

What your code is doing is saying "Look within my GameObject for a BombDropScript, most of the time the script won't be attached to the same GameObject.

Also use a setter and getter for maxBombs.

public class BombDrop : MonoBehaviour
{
    public void setMaxBombs(int amount)
    {
        maxBombs += amount;
    }

    public int getMaxBombs()
    {
        return maxBombs;
    }
}

Upvotes: 29

Milad Qasemi
Milad Qasemi

Reputation: 3059

use it in start instead of awake and dont use Destroy(gameObject); you are destroying your game Object then you want something from it

void Start () {
     BombDropScript =gameObject.GetComponent<BombDrop> ();
     collider = gameObject.GetComponent<BoxCollider2D> ();

     // Call the Explode function after a few seconds
     Invoke("Explode", time);

 }

void Explode() {
//..
  //..
//at last
Destroy(gameObject);
 }

if you want to access a script in another gameObject you should assign the game object via inspector and access it like that

 public gameObject another;
void Start () {
     BombDropScript =another.GetComponent<BombDrop> ();
}

Upvotes: 2

Related Questions