如何在Unity上为Text Mesh分配一个死亡计数器?

时间:2019-06-16 23:19:07

标签: c# unity3d

我正在尝试使用一个带有死亡计数器的2D平台机,但是我遇到了一个问题。 这是我附加到3D文本的脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class DeathCounter : Respawn
{
    public Text DeathCount;
    public void SetText(int text)
    {
        string deathsS = deaths.ToString();
        DeathCount.text = deathsS;
    }
}

它什么都不做。 我正在寻求帮助。 我该怎么办?

如果需要,这里是“重生”脚本:

using System.Collections;
using UnityEngine.SceneManagement;
using System.Collections.Generic;
using UnityEngine;

public class Respawn : MonoBehaviour
{

    public int deaths;

    private Scene scene;

    void Start()
    {
        scene = SceneManager.GetActiveScene();
    }

    void OnCollisionEnter2D(Collision2D col)
    {
        if(col.transform.CompareTag("Player"))
        {
            deaths = deaths + 1;
            Debug.Log("You are dead");
            System.Threading.Thread.Sleep(500);
            SceneManager.LoadScene(0);
        }

    }

}

非常感谢您的帮助! 祝你有美好的一天。

2 个答案:

答案 0 :(得分:0)

我要做的第一件事是从您的Respawn类中删除DeathCounter的继承,因为它没有扩展Respawn的功能。然后,我将功能设置为使用传入的参数来设置文本值。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class DeathCounter : MonoBehaviour
{
    public Text DeathCount;
    public void SetText(String text)
    {
        DeathCount.text = "Death Count: " + text;
    }
}

然后,在其他班级进行碰撞检查时,您可以将死亡计数值作为将DeathCount文本设置为的值。

using System.Collections;
using UnityEngine.SceneManagement;
using System.Collections.Generic;
using UnityEngine;

public class Respawn : MonoBehaviour
{

    public int deaths;

    //Reference to your DeathCounter script
    public DeathCounter dCounter;

    private Scene scene;

    void Start()
    {
        scene = SceneManager.GetActiveScene();
    }

    void OnCollisionEnter2D(Collision2D col)
    {
        if(col.transform.CompareTag("Player"))
        {
            deaths = deaths + 1;
            //New line here, with passed in script for updating as a reference
            dCounter.SetText(deaths.ToString());
            Debug.Log("You are dead");
            System.Threading.Thread.Sleep(500);
            SceneManager.LoadScene(0);
        }

    }

}

编辑::一个脚本版本...

using System.Collections;
using UnityEngine.SceneManagement;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Respawn : MonoBehaviour
{

    public int deaths;

    //Reference to your Text, dragged in via the inspector
    public Text deathCount;

    private Scene scene;

    void Start()
    {
        scene = SceneManager.GetActiveScene();
    }

    void OnCollisionEnter2D(Collision2D col)
    {
        if(col.transform.CompareTag("Player"))
        {
            deaths = deaths + 1;
            //Just update the referenced UI text
            deathCount.text = "Death Count: " + deaths;
            Debug.Log("You are dead");
            System.Threading.Thread.Sleep(500);
            SceneManager.LoadScene(0);
        }

    }

}

答案 1 :(得分:0)

问题

基本上位于LoadScene中:

您增加deaths但是,然后重新加载场景→您还重新加载了Respawn实例,因此deaths仍将具有其原始值,因此可能是0

您甚至没有调用SetText方法,但是即使重新加载场景时,也会重新加载Text组件,并且将具有您未调用过的原始文本完全是SetText方法。


解决方案

在这种情况下,我要修复它,我将使用

public class Respawn : MonoBehaviour
{
    public static int deaths{ get; private set; }

    ...

如果值是static,则它不绑定到Respawn的某个实例,而是直接以Respawn类型“生存”。因此,在重新加载场景时,它也保持其当前值。 {get; private set;}将其从 field 转换为 property ,其他所有类都可以读取,但只能由Respawn类编写。

您进一步从不希望使用类似的

System.Threading.Thread.Sleep(500);

在Unity主线程中。这将完全冻结主线程,如果您例如稍后添加任何动画等,该应用将完全冻结。而是使用Coroutine之类的

void OnCollisionEnter2D(Collision2D col)
{
    if(!col.transform.CompareTag("Player")) return;

    deaths += 1;
    Debug.Log("You are dead");

    StartCoroutine(Reload());
}

private IEnumerator Reload()
{
    yield return new WaitForSeconds(0.5f);

    SceneManager.LoadScene(0);
}

最后,您必须在加载场景之后设置Text,以便在重新加载的场景中也对其进行更新。

public class DeathCounter : Respawn
{
    public Text DeathCount;

    // automatically called when scene is reloaded
    private void OnEnable()
    {
        DeathCount.text = deaths.ToString();
    }
}

旁注:

Respawn中,您存储

scene = SceneManager.GetActiveScene();

但后来从不使用它,反而还是使用

SceneManager.LoadScene(0);

所以我将摆脱该Start方法..它只会导致不必要的开销。