如何通过GetComponent从另一个Gameobject的脚本中访问变量?

17

我搜索了一下,但是就是无法让它工作。我想我可能不知道正确的语法,或者只是没有完全掌握上下文。

我有一个BombDrop脚本,其中包含一个public int。我通过使用public static使其起作用,但有人说这是一种非常糟糕的编程习惯,我应该学习封装性。这是我的写法:

BombDrop脚本:

 <!-- 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);

 }
}

我希望Bomb脚本能够访问附加到Bombprefab游戏对象的脚本BombDrop中的maxBombs整数,这样当炸弹被销毁时,它会在BombDrop中将maxBombs增加1。

需要引用此脚本的是Bomb脚本本身。

 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);
在文档中,它说应该像这样做。
BombDropScript = otherGameObject.GetComponent<BombDrop>();

但这并没有起作用。也许我只是不理解这里的语法。它应该说 otherGameObject 吗?因为那样没什么作用。我仍然在 BombDropScript.maxBombs 中的 explode() 函数下面收到错误消息:"对象引用未设置为对象实例"。


你可以使用这个代码:BombDropScript = this.GetComponent<BombDrop>(); - Milad Qasemi
嗯,还是同样的错误。 : / - DoubleCode
可能是重复的问题:什么是NullReferenceException,如何修复它? - CodeSmile
1
可能是重复的问题:不知道如何获取敌人的生命值 - apxcode
3个回答

27

你需要找到包含所需脚本组件的GameObject,并获取对其的引用。确保该GameObject已经在场景中,否则Find将返回null

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

然后您可以获取脚本:

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

然后你就可以访问脚本中的变量和函数。

 bScript.foo();

我刚意识到我几天前回答过一个非常相似的问题,可以在这里查看: 不知道如何获取敌人的生命值


我会稍微扩展一下你的问题,因为我已经回答过了。

你的代码正在寻找“在我的游戏对象中查找BombDropScript”,但大多数情况下脚本并未附加到同一游戏对象上。

同时使用maxBombs的setter和getter方法。

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

    public int getMaxBombs()
    {
        return maxBombs;
    }
}

是的,我的玩家有“BombDrop”脚本,它实例化了“bombPrefab”炸弹预制件。因此,在实例化之前,该预制件不在场景中。但也许一旦它被实例化,目标就能正常工作了?所以,无论如何都能找到它的目标?好的,那将非常有帮助:)我的代码只是我从自己的错误逻辑中组合出来的。 - DoubleCode
还有一件事!我计划拥有不止一个玩家,所以炸弹需要知道是谁创建的。这样它就不会重置其他玩家的计数器。但这是后话了。首先我只需要引用:) - DoubleCode
实际上,我收回之前的说法。按照你设置的方式,确实需要调用BombDrop。我没有考虑到其他玩家!所以,使用我的代码是没问题的。请确保为maxBombs添加setter和getter,公共变量是很危险的。 - apxcode
正确,预设应不在场景中,只需确保BombDrop始终在场景中即可。 - apxcode
1
谢谢:)我会从文档中查看设置和获取逻辑。 - DoubleCode
显示剩余3条评论

2

在启动时使用它,而不是使用“唤醒”,不要使用 Destroy(gameObject);,因为你正在销毁游戏对象,然后希望从中获取一些东西。

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);
 }

如果你想访问另一个GameObject中的脚本,你应该通过检查器分配这个GameObject,并像这样访问它。

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

嗯,还是不行。也许是explode方法的问题? - DoubleCode
啊,我明白了,所以它在被调用之前就销毁了吗?但是如果我想在它被销毁后改变变量怎么办呢?如果我在Explode()中将其设置为销毁之前,它就永远不会被销毁。 - DoubleCode
最后一件要做的事情就是像这样摧毁掉游戏物体:void Explode() { //.. //.. //最后 Destroy(gameObject); } - Milad Qasemi
没有 BombDrop 附加到玩家,另一个游戏对象上。而 Bomb 脚本附加到 bombPrefab 上。 - DoubleCode
我编辑了我的答案,向您展示如何访问另一个游戏对象中的脚本。 - Milad Qasemi
显示剩余6条评论

0
可以使用这个:
entBombDropScript.maxBombs += 1;

之前:

Destroy(gameObject);

我只想说,在Destroying游戏对象之前,您可以增加maxBombs值。这是必要的,因为如果您先销毁游戏对象,然后再增加值,那么此时您的脚本BombDropScript的引用将消失,您将无法修改其中的值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接