带有 Healthbar 的 Unity-Breakout 游戏

Posted

技术标签:

【中文标题】带有 Healthbar 的 Unity-Breakout 游戏【英文标题】:Unity-Breakout Game with a Healthbar 【发布时间】:2017-10-20 18:51:32 【问题描述】:

我正在制作一个突围游戏,我想添加一个生命条,当球接触带有“危险”标签的某个对象时,生命条会减少。我有一个游戏管理器脚本和一个拾取交互脚本,但是考虑到我将玩家健康元素放入我的GM 脚本,所以我可以将它附加到调用游戏管理器的空游戏对象,因为实际的玩家不在层次结构中,而是在运行时实例化。我希望我不必为了这个目的而重做整个事情。如果有人可以帮助我解决这个问题,我将不胜感激。

这是我的 GM 脚本:

public class GM : MonoBehaviour


    public int lives = 3;
    public int bricks = 20;
    public float resetDelay = 1f;
    public Text livesText;

    public GameObject gameOver;
    private GameObject clonePaddle;
    public GameObject youWon;
    public GameObject bricksPrefab;
    public GameObject paddle;
    public GameObject deathParticles;
    public static GM instance = null;

    public int startingHealth = 100;
    public int currentHealth;
    public Slider healthSlider;

    bool isDead;
    bool damaged;



    void Awake()
    
        currentHealth = startingHealth;
        TakeDamage(10);

        if (instance == null)
            instance = this;
        else if (instance != this)
            Destroy(gameObject);

        Setup();

    

    public void TakeDamage(int amount)
    
        damaged = true;

        currentHealth -= amount;
        healthSlider.value = currentHealth;

        if (currentHealth <= 0)
        
            LoseLife();
        

    

    public void Setup()
    
        clonePaddle = Instantiate(paddle, transform.position, Quaternion.identity) as GameObject;
        Instantiate(bricksPrefab, transform.position, Quaternion.identity);
    


    void CheckGameOver()
    
        if (bricks < 1)
        
            youWon.SetActive(true);
            Time.timeScale = .25f;
            Invoke("Reset", resetDelay);
        

        if (lives < 1)
        
            gameOver.SetActive(true);
            Time.timeScale = .25f;
            Invoke("Reset", resetDelay);
        

    

    void Reset()
    
        Time.timeScale = 1f;
        Application.LoadLevel(Application.loadedLevel);
    

    public void LoseLife()
    
        lives--;
        livesText.text = "Lives: " + lives;
        Instantiate(deathParticles, clonePaddle.transform.position, Quaternion.identity);
        Destroy(clonePaddle);
        Invoke("SetupPaddle", resetDelay);
        CheckGameOver();
    

    void SetupPaddle()
    
        clonePaddle = Instantiate(paddle, transform.position, Quaternion.identity) as GameObject;
    

    public void DestroyBrick()
    
        bricks--;
        CheckGameOver();
    

这是我的取件脚本:

public class Pickups : MonoBehaviour 

    public float PaddleSpeedValue = 0.5f;

    private bool isActive = false;

    public float thrust=20f;

    public Rigidbody rb;

    GameObject player;



    private void OnTriggerEnter(Collider other)
    
         if (other.tag == "Hazard")
        
            isActive = true;
            Destroy(other.gameObject);
        
    


【问题讨论】:

如果您在问题编辑器中分块选择整个文本块并按 Ctrl+K,编辑器会将整个文本缩进四个空格,从而将其格式化为代码。 或者您可以直接按下代码按钮...这是带有 符号的按钮。 --- 另外,只是提醒一下,这是 Singleton 统一模式的非常幼稚且容易出错的实现。看看Singleton implementation reference at the wiki;它有点过时了,经验丰富的程序员可以让它变得更好,但这是一个好的开始,并且已经比你的实现更好。 【参考方案1】:

Pickups 类根本不应该有或存储对播放器的引用(尽管从您的问题中不清楚这是附加到播放器还是附加到其他东西的脚本)。你的游戏管理器类应该。毕竟,它是负责管理游戏的类,其中包括玩家。从那里,您可以使用GetComponent&lt;?&gt;() 访问附加到玩家游戏对象的任何脚本。

然后,由于GM 包含对其自身的公共静态引用,因此任何其他类都可以根据需要通过执行GM.instance.player 来获取对播放器的引用,即使播放器被创建和销毁多次(GM 应该总是引用当前的!)

大概clonePaddle字段是玩家(的游戏对象),你所要做的就是公开它。

【讨论】:

关于“公开”的坏建议。将不需要公开的字段设为公开的字段是不好的做法。在 private 字段上使用 [SerializeField]public property 来处理对外部脚本的访问/来自外部脚本的访问。 --- 如果不是那样的话,应该得到 +1。 --- 也可以解释Singleton,并警告 OP 的实现是如何幼稚且容易出错的,但这与实际问题无关,所以嗯。

以上是关于带有 Healthbar 的 Unity-Breakout 游戏的主要内容,如果未能解决你的问题,请参考以下文章

我的世界服务器插件帮忙翻译

unity初学6——简易的UI制作(血条制作)和音频加入以及NPC的对话气泡(2d)

带有多个链接的 NSAttributedString 的 UILabel,带有行限制,显示尾部截断,带有未见文本的 NSBackgroundColorAttributeName

使用带有 uuencode 的“sendmail”发送邮件,并带有主题

带有和不带有聚合的 sql 查询

带有滚动的 Div 和带有绝对位置的内容