如何更改共享脚本中的变量,而不影响共享该脚本的所有其他游戏对象?

Posted

技术标签:

【中文标题】如何更改共享脚本中的变量,而不影响共享该脚本的所有其他游戏对象?【英文标题】:How to change a variable in a shared script, without affecting all the other game objects that share that script? 【发布时间】:2021-06-17 21:50:15 【问题描述】:

我整天都在尝试解决这个问题,因为我不想为每个子弹制作单独的脚本,而是想要一个单独的 EnemyBulletMovement 脚本,它可以以不同的方式移动每个子弹,具体取决于BulletType int 在我实例化它时输入它。

问题是,如果我同时发射多个子弹,一旦实例化另一个子弹,它们都会改变 BulletType,因为它们都共享同一个脚本。

我的目标是让所有项目符号都有一个私有脚本,但无论我尝试什么,每次我尝试为其中一个项目更改它时,仍然会为所有活动项目符号更改变量。

EnemyController 脚本,用于实例化子弹并为它们提供 BulletType 值:

 GameObject enemyBullet = ObjectPooler.SharedInstance.GetPooledEnemyBullet();
        if (enemyBullet != null)
        
            Quaternion rotationAmount = Quaternion.Euler(0, 0, 0);
            Quaternion postRotation = transform.rotation * rotationAmount;
            enemyBullet.transform.position = transform.position;
            enemyBullet.transform.rotation = postRotation;
            enemyBullet.SetActive(true);
            enemyBullet.GetComponent<EnemyBulletMovement>().SetBullet(2);

        
        GameObject enemyBullet2 = ObjectPooler.SharedInstance.GetPooledEnemyBullet();
        if (enemyBullet2 != null)
        
            Quaternion rotationAmount = Quaternion.Euler(0, 3, 0);
            Quaternion postRotation = transform.rotation * rotationAmount;
            enemyBullet2.transform.position = transform.position;
            enemyBullet2.transform.rotation = postRotation;
            enemyBullet2.SetActive(true);
            enemyBullet2.GetComponent<EnemyBulletMovement>().SetBullet(0);
        

共享的 EnemyBulletMotion 脚本,从上述脚本中获取 bulletType。这就是问题所在:

public void SetBullet(int typeIndex)

    bulletType = typeIndex;
    Debug.Log(bulletType);

private void BulletMotion()

    
    if (bulletType == 0)
    
        rb.velocity = pos;
    
    if (bulletType == 1)
    
        axis = Mathf.Sin(Time.deltaTime * -frequency) * magnitude * transform.up;  // Up down Wave motion
        transform.Rotate(Vector3.forward * sideMag);                               // Side Sway Motion (+ Wave = Spiral Motion)
        rb.velocity = pos + axis;                                                  // Combine all Motions
    
    if (bulletType == 2)
    
        Debug.Log("Shootin");
        axis = Mathf.Sin(Time.deltaTime * -frequency) * magnitude * transform.up;  // Up down Wave motion
        transform.Rotate(Vector3.forward * -sideMag);                              // Side Sway Motion (+ Wave = Spiral Motion)
        rb.velocity = pos + axis;                                                  // Combine all Motions
    


编辑:这个 Debug Shootin 从来没有出现在我的控制台中,所以可能bulletType 在这里没有被正确读取?为了澄清,第一个 Debug.Log(bulletType); 返回 0 或 2 所以它正在工作。但是第二个Debug.Log("Shootin"); 永远不会被打印出来。

我尝试了私有的、静态的,并从整个 EnemyBulletMovement 脚本中创建了一个实例,但没有任何效果。

当我调试此代码时,脚本工作,bulletType 将从 2 更改为 0 并返回,但是当它这样做时,它会更改两个项目符号,因此两者的飞行方式相同,而我想要的是每个子弹跟随它自己的动作。如果没有办法做到这一点,我将不得不为每个子弹动作创建一个单独的脚本,但我在这里只显示 2 个,而且我已经有很多,这就是为什么我想尝试这个并使它与 @987654326 一起工作@ 然后再使用case statements

编辑:在下面添加了 ObjectPooler 脚本。

public List<GameObject> pooledEnemyBullets;
public GameObject EnemyBulletToPool;
public int EnemyBulletAmountToPool;
  pooledEnemyBullets = new List<GameObject>();
public static ObjectPooler SharedInstance;

void Awake()

    SharedInstance = this;



void Start()

    for (int i = 0; i < EnemyBulletAmountToPool; i++)
    
        GameObject obj3 = (GameObject)Instantiate(EnemyBulletToPool);
        obj3.SetActive(false);
        pooledEnemyBullets.Add(obj3);
    

public GameObject GetPooledEnemyBullet()

    //1
    for (int i = 0; i < pooledEnemyBullets.Count; i++)
    
        //2
        if (!pooledEnemyBullets[i].activeInHierarchy)
        
            return pooledEnemyBullets[i];
        
    
    //3   
    return null;


【问题讨论】:

【参考方案1】:

子弹类型应声明为private int bulletType。如果您将项目符号类型声明为private static int bulletType,则所有项目符号都将相同。

如果它已经被声明为private int bulletType,那么你应该检查你使用对象池的逻辑。您可能会一遍又一遍地处理同一个项目符号,或者处理池中的所有项目符号。

【讨论】:

感谢您的回答,我的 bulletType 被定义为私有 int。我已编辑问题并添加了我的 ObjectPooler 脚本。 我不知道如何,但它已修复!和SharedInstance = this;有关系吗? @eriksprogram 只是一个疯狂的猜测,但我会尝试activeSelf 而不是activeInHieararchy。可能是池程序在同一个调用中返回相同的对象。还可以尝试在 pooler Instantiate 中设置一个唯一的 obj3.name,并使用项目符号类型将其登录到 BulletMotion 以查看您是否正在处理正确的对象。

以上是关于如何更改共享脚本中的变量,而不影响共享该脚本的所有其他游戏对象?的主要内容,如果未能解决你的问题,请参考以下文章

在未加载重复项的多个 python 脚本之间共享变量(来自文件的数据)

如何在 Perl 脚本之间共享 ENV 变量

如何在两个单独的脚本中导入共享变量?

如何与子线程共享变量?

变量的四种作用域是?

影响所有图像的脚本而不是仅包含某些文本的div中的图像(jQuery)