分数计数不适用于预制件
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);
}
}
}
这是一个半复杂的问题,但我会尽力解释它:
我正在制作这款手机游戏,您必须在其中射击四个立方体。我正在尝试做到这一点,所以当立方体被子弹击中时,它们会被摧毁,并且 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);
}
}
}