分数计数不适用于预制件

Score Count not working on a prefab

这是一个半复杂的问题,但我会尽力解释它:

我正在制作这款手机游戏,您必须在其中射击四个立方体。我正在尝试做到这一点,所以当立方体被子弹击中时,它们会被摧毁,并且 UI 文本会显示 1/4,每次射击立方体时都会显示为 4/4。但这真的很奇怪,即使所有四个立方体都被射击并摧毁,它也只能算到 1/4。我将这两个脚本放在项目符号上(我制作了两个单独的脚本以查看是否可以执行任何操作,但没有)

为了更好地理解我在说什么,这里是游戏本身的屏幕截图。

我已经使用 Unity 大约 6 天了,所以对于我说的任何菜鸟式的言论,我深表歉意。

编辑

所以我将这两个脚本组合到一个空的游戏对象上,这是新脚本:

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class GameManagerScript : MonoBehaviour {
public GameObject cubes;
public Text countText;
public int cubeCount;
public Transform target;

// Use this for initialization
void Start () {

}

void OnTriggerEnter(Collider other)
{
    cubes = other.gameObject;
}

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

    cubes.transform.position = Vector3.MoveTowards(transform.position, target.position, 1f * Time.deltaTime);


    if (cubes.gameObject.tag == "BULLET")
    {

        cubeCount = cubeCount + 1;
        countText.text = cubeCount + "/4";
        cubes.SetActive(false);
    }
}
}

另一个编辑

我尝试了所有方法,那么有没有办法检测到层次结构中父级中的所有子级何时被销毁?而不是向上计数?这可以给出一个更好的主意:

所以我希望能够检测到 Cube、Cube1、Cube2 和 Cube3 何时全部被销毁。

答案很简单:因为每个子弹都有那个脚本,所以每个子弹都有自己的分数。

对于乐谱之类的东西,您需要一个单独的位置来存储它,例如充当游戏控制器的空游戏对象上的脚本。只需在碰撞中访问它并增加分数(也许在这里看看单身人士)。

您可以将这两个脚本结合起来,实际上最好不要将它放在子弹上,而是放在目标上,因为它们可能更少,这会节省一些性能。 (而且从逻辑的角度来看更有意义。)

编辑:
我假设您使用带有预制件的 Instantiate 创建项目符号。预制件(= 蓝图)实际上并不在游戏中(只有 scene/hierarchy 中的对象在游戏中)。每次使用 Instantiate 都会使用它自己的组件版本创建该预制件的新实例。单例是一种只能存在一次的东西,但这也是我在这里提到它的原因,你可以在没有像Find这样的东西的情况下访问它。它是某种静态的。一个空的游戏对象只是一个没有视觉效果的对象。您可以轻松地统一创建一个(右键单击>创建空)。它们通常用作容器和脚本持有者。

编辑:
你想要的是:

  • 一个带有保存分数的脚本的空游戏对象。
  • 使用 OnTriggerEnter 检测碰撞的脚本,此脚本将出现在子弹或目标上。

现在,这只是一个非常简单的例子,可以进行优化,但我希望这会给你一个想法。
得分脚本,放置在一个空的游戏对象上:

public class ScoreManager : MonoBehaviour
{
    public Text scoreText;    // the text object that displays the score, populate e.g. via inspector

    private int score;

    public void IncrementScore()
    {
        score++;
        scoreText.text = score.ToString();
    }
}

子弹版本的碰撞脚本:

public class Bullet : MonoBehaviour
{
    private ScoreManager scoreManager;

    private void Start()
    {
        scoreManager = GameObject.FindWithTag("GameManager").GetComponent<ScoreManager>();    // give the score manager empty gameobject that tag
    }

    private void OnTriggerEnter(Collider other)
    {
        if(other.CompareTag("Target") == true)
        {
             // update score
             scoreManager.IncrementScore();
             // handle target, in this example it's just destroyed
             Destroy(other.gameObject);
        }
    }
}