【问题标题】:Player Score not being updated on the TextMeshPro component没有在 TextMeshPro 组件上更新玩家分数
【发布时间】:2020-08-17 10:26:24
【问题描述】:

我刚刚创建了一个 TextMeshPro 文本组件,然后立即从中创建了一个 PreFab。然后,我将此预制件附加到脚本(通过将其拖动到序列化字段中),其中砖块被破坏,我正在通过 .text 属性更新文本。

当我 Debug.Log() score.text 时,它给了我正确的值。但是 UI 上的分数仍然是 0。没有出现任何错误,我已经多次交叉检查了代码。

代码如下:

using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;

public class BlockScript : MonoBehaviour
{
    [SerializeField] TextMeshProUGUI scoreText;
    [SerializeField] LevelScript levelScript;
    [SerializeField] AudioClip clip;
    static int gameScore;
    private void Start()
    {
        gameScore = 0;
    }
    private void OnCollisionEnter2D(Collision2D collision)
    {
        // PlayClipAtPoint creates a temporary gameObject that is created in the world space so that
        // the sound keeps on playing even though the gameobject is deleted or destroyed
        AudioSource.PlayClipAtPoint(clip, Camera.main.transform.position);
        gameScore += 83;
        scoreText.text = gameScore.ToString();
        Destroy(gameObject);        
        Debug.Log("Object name: " + collision.gameObject.name);
        Debug.Log("GameScore: " + gameScore);
        Debug.Log("Frame Count: " + Time.frameCount);       
        Debug.Log(scoreText.text);
    }
}

日志:

Object name: Ball
UnityEngine.Debug:Log(Object)
 
GameScore: 83
UnityEngine.Debug:Log(Object)
 
Frame Count: 162
UnityEngine.Debug:Log(Object)
 
Object name: Ball
UnityEngine.Debug:Log(Object)
 
GameScore: 166
UnityEngine.Debug:Log(Object)
 
Frame Count: 337
UnityEngine.Debug:Log(Object)

另外,我注意到只能将预制件拖到预制件的序列化字段上,而不是普通的游戏对象。请帮我解决这个问题,如果您需要有关此问题的任何其他信息,请告诉我。

同样在下图,你可以看到我停止玩游戏后,分数显示为747。但在游戏过程中,分数为0。

所以简而言之,在玩游戏时分数不会更新,但只有在我停止播放按钮后才能看到最终分数。

用户界面:

【问题讨论】:

  • 为什么你的 gameScore 是静态的?不,不需要将预制件放在序列化字段上。这里可能发生的是需要 SerializedField 才能在编辑器上查看您的私有变量。将这些变量公开并告诉我现在您是否可以将其删除为非预制游戏对象。另请注意,静态字段不会显示在编辑器上。
  • @Lotan,我将 gameScore 设为静态,因为我希望在加载下一个关卡时分数不会变回 0。只是做一些反复试验的东西。我把它变成了一个正常的变量。现在,文本应该在击中一个块后更新为 83,但文本在 UI 中仍为 0。如果我错了,请纠正我,但由于我正在破坏块对象,它是否是罪魁祸首?最后,我尝试在块预制的序列化字段中放置一个普通的 textmeshpro 对象,但它不允许我这样做。我只需要删除 scoreText 的预制件。
  • 我认为您的代码/项目中还有其他内容。应该在 Destroy 之前调用 Destroy 命令之后的此调试日志。丢弃预制件的问题不应该存在,我唯一能想到的是您对“普通 textMeshPro 对象”的定义与我的不同。
  • @Lotan 通常,我的意思是我们都将 textmeshpro 对象作为 Canvas 的子对象删除的方式
  • 没关系,我想我现在明白了,你想说的是:将它附加到预制目录上的预制,而不是已经在场景中实例化的预制,对吗?如果是,那么您是对的,您需要另一个预制件将其链接到现有的(在您的项目中,而不是场景中)预制件。无论如何,您可以做的是,在实例化您的块时,在运行时引用您的文本。

标签: unity3d


【解决方案1】:

所以这里的问题是一个错误的参考。

不是引用场景Score 对象,而是指向编辑器预制件,而不是当前在场景中实例化的预制件。

一个快速的解决方案:

using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;

public class BlockScript : MonoBehaviour
{
    [SerializeField] TextMeshProUGUI scoreText;
    [SerializeField] LevelScript levelScript;
    [SerializeField] AudioClip clip;
    static int gameScore;
    private void Start()
    {
        gameScore = 0;
    }
    private void OnCollisionEnter2D(Collision2D collision)
    {
        // PlayClipAtPoint creates a temporary gameObject that is created in the world space so that
        // the sound keeps on playing even though the gameobject is deleted or destroyed
        AudioSource.PlayClipAtPoint(clip, Camera.main.transform.position);
        gameScore += 83;

        //Find the scene reference
        scoreText = GameObject.FindGameObjectWithTag("ScoreText");
        
        scoreText.text = gameScore.ToString();

        Debug.Log("Object name: " + collision.gameObject.name);
        Debug.Log("GameScore: " + gameScore);
        Debug.Log("Frame Count: " + Time.frameCount);       
        Debug.Log(scoreText.text);

        Destroy(gameObject);                
    }
}

另一种,避免FindByTag 方法(一种昂贵的方法)是简单地将Score 游戏对象拖放到块scoreText 变量中。

【讨论】:

    猜你喜欢
    • 2016-01-06
    • 2017-11-11
    • 2021-10-17
    • 2011-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多