Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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()

like image 709
DoubleCode Avatar asked Oct 24 '14 15:10

DoubleCode


People also ask

How do you get a variable from another script Unity?

Getting a variable from another script in Unity can be pretty straightforward. In fact, even if you're only just getting started with the basics of Unity, chances are you've already created a public reference between a script variable and another object, by dragging and dropping it in the Inspector.


2 Answers

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;
    }
}
like image 128
apxcode Avatar answered Oct 06 '22 23:10

apxcode


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> ();
}
like image 31
Milad Qasemi Avatar answered Oct 06 '22 23:10

Milad Qasemi