简体   繁体   English

Unity 2D健康栏

[英]Unity 2D health bar

I am new to coding and Unity 我是编码和Unity的新手

I have the health bar appearing on my screen, but I am not sure how to link the Health script of the health bar to my player script and my player's health script. 我的健康栏出现在我的屏幕上,但我不确定如何将健康栏的健康脚本链接到我的播放器脚本和播放器的健康脚本。 Simply, I want to make it so when my player gets shot my health bar will lose a heart 简单地说,我想这样做,当我的球员被击中时,我的健康棒会失去一颗心

my health bar script 我的健康栏脚本

using UnityEngine;
using System.Collections;

public class Health : MonoBehaviour {

    public int startHealth;
    public int healthPerHeart;

    private int maxHealth;
    private int currentHealth;

    public Texture[] heartImages;
    public GUITexture heartGUI;

    private ArrayList hearts = new ArrayList();

    // Spacing:
    public float maxHeartsOnRow;
    private float spacingX;
    private float spacingY;


    void Start () {
        spacingX = heartGUI.pixelInset.width;
        spacingY = -heartGUI.pixelInset.height;

        AddHearts(startHealth/healthPerHeart);
    }

    public void AddHearts(int n) {
        for (int i = 0; i <n; i ++) { 
            Transform newHeart = ((GameObject)Instantiate(heartGUI.gameObject,this.transform.position,Quaternion.identity)).transform; // Creates a new heart
            newHeart.parent = transform;

            int y = (int)(Mathf.FloorToInt(hearts.Count / maxHeartsOnRow));
            int x = (int)(hearts.Count - y * maxHeartsOnRow);

            newHeart.GetComponent<GUITexture>().pixelInset = new Rect(x * spacingX,y * spacingY,58,58);
            newHeart.GetComponent<GUITexture>().texture = heartImages[0];
            hearts.Add(newHeart);

        }
        maxHealth += n * healthPerHeart;
        currentHealth = maxHealth;
        UpdateHearts();
    }


    public void modifyHealth(int amount) {
        currentHealth += amount;
        currentHealth = Mathf.Clamp(currentHealth,0,maxHealth);
        UpdateHearts();
    }

    void UpdateHearts() {
        bool restAreEmpty = false;
        int i =0;

        foreach (Transform heart in hearts) {

            if (restAreEmpty) {
                heart.guiTexture.texture = heartImages[0]; // heart is empty
            }
            else {
                i += 1; // current iteration
                if (currentHealth >= i * healthPerHeart) {
                    heart.guiTexture.texture = heartImages[heartImages.Length-1]; // health of current heart is full
                }
                else {
                    int currentHeartHealth = (int)(healthPerHeart - (healthPerHeart * i - currentHealth));
                    int healthPerImage = healthPerHeart / heartImages.Length; // how much health is there per image
                    int imageIndex = currentHeartHealth / healthPerImage;


                    if (imageIndex == 0 && currentHeartHealth > 0) {
                        imageIndex = 1;
                    }

                    heart.guiTexture.texture = heartImages[imageIndex];
                    restAreEmpty = true;
                }
            }

        }
    }
}

my player script 我的播放器脚本

/// <summary>
/// Player controller and behavior
/// </summary>
public class PlayerScript : MonoBehaviour
{
    public Health health;
    /// <summary>
    /// 1 - The speed of the ship
    /// </summary>
    public Vector2 speed = new Vector2(50, 50);

    // 2 - Store the movement
    private Vector2 movement;

    void OnCollisionEnter2D(Collision2D collision)
    {
        bool damagePlayer = false;

        // Collision with enemy
        EnemyScript enemy = collision.gameObject.GetComponent<EnemyScript>();
        if (enemy != null)
        {
            // Kill the enemy
            HealthScript enemyHealth = enemy.GetComponent<HealthScript>();
            if (enemyHealth != null) enemyHealth.Damage(enemyHealth.hp);

            damagePlayer = true;

        }

        // Damage the player
        if (damagePlayer)
        {
            HealthScript playerHealth = this.GetComponent<HealthScript>();
            if (playerHealth != null) playerHealth.Damage(1);

        }
    }



    void Update()
    {
        // 3 - Retrieve axis information
        float inputX = Input.GetAxis("Horizontal");
        float inputY = Input.GetAxis("Vertical");

        // 4 - Movement per direction
        movement = new Vector2(
            speed.x * inputX,
            speed.y * inputY);

        // 5 - Shooting
        bool shoot = Input.GetButtonDown("Fire1");
        shoot |= Input.GetButtonDown("Fire2");
        // Careful: For Mac users, ctrl + arrow is a bad idea

        if (shoot)
        {
            WeaponScript weapon = GetComponent<WeaponScript>();
            if (weapon != null)
            {
                // false because the player is not an enemy
                weapon.Attack(false);
            }
        }
        // 6 - Make sure we are not outside the camera bounds
        var dist = (transform.position - Camera.main.transform.position).z;

        var leftBorder = Camera.main.ViewportToWorldPoint(
            new Vector3(0, 0, dist)
            ).x;

        var rightBorder = Camera.main.ViewportToWorldPoint(
            new Vector3(1, 0, dist)
            ).x;

        var topBorder = Camera.main.ViewportToWorldPoint(
            new Vector3(0, 0, dist)
            ).y;

        var bottomBorder = Camera.main.ViewportToWorldPoint(
            new Vector3(0, 1, dist)
            ).y;

        transform.position = new Vector3(
            Mathf.Clamp(transform.position.x, leftBorder, rightBorder),
            Mathf.Clamp(transform.position.y, topBorder, bottomBorder),
            transform.position.z
            );

    }

    void FixedUpdate()
    {
        // 5 - Move the game object
        rigidbody2D.velocity = movement;
    }

    void OnDestroy() 
    {
        Application.LoadLevel("gameOver"); 
    } 

}

and my player's health script 和我的播放器的健康脚本

using UnityEngine;

/// <summary>
/// Handle hitpoints and damages
/// </summary>
public class HealthScript : MonoBehaviour
{   
    /// <summary>
    /// Total hitpoints
    /// </summary>
    public int hp = 1;

    /// <summary>
    /// Enemy or player?
    /// </summary>
    public bool isEnemy = true;

    /// <summary>
    /// Inflicts damage and check if the object should be destroyed
    /// </summary>
    /// <param name="damageCount"></param>
    public void Damage(int damageCount)
    {
        hp -= damageCount;

        if (hp <= 0)
        {
            // 'Splosion!
            SpecialEffectsHelper.Instance.Explosion(transform.position);

            // Dead!
            Destroy(gameObject);
        }
    }

    void OnTriggerEnter2D(Collider2D otherCollider)
    {
        // Is this a shot?
        ShotScript shot = otherCollider.gameObject.GetComponent<ShotScript>();
        if (shot != null)
        {
            // Avoid friendly fire
            if (shot.isEnemyShot != isEnemy)
            {
                Damage(shot.damage);

                // Destroy the shot
                Destroy(shot.gameObject); // Remember to always target the game object, otherwise you will just remove the script
            }
        }
    }
}

With new UI system in Unity 4.6 it is really easy to create a health bar. 使用Unity 4.6中的新UI系统,可以轻松创建健康栏。

  • GameObject->UI->Image GameObject-> UI->图像
  • Put your health bar sprite in image. 将健康栏精灵放入图像中。
  • Change the Image type to Filled. 将图像类型更改为已填充。 Then you can play with Fill amount property and also control in through code 然后你可以玩Fill amount属性并通过代码控制

In your PlayerScript you retrieve the HealthScript with the following code: 在您的PlayerScript您可以使用以下代码检索HealthScript

HealthScript playerHealth = this.GetComponent<HealthScript>();

If you want to call methods on the Health script you would do something similar. 如果要在Health脚本上调用方法,则可以执行类似的操作。

Health healthBar = this.GetComponent<Health>();
healthBar.modifyHealth(amountOfDamage);

This assumes all 3 scripts are on the same Game object. 这假设所有3个脚本都在同一个Game对象上。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM