Unity 2D健康栏

时间:2014-04-21 22:45:20

标签: c# unity3d

我是编码和Unity的新手

我的健康栏出现在我的屏幕上,但我不确定如何将健康栏的健康脚本链接到我的播放器脚本和播放器的健康脚本。简单地说,我想这样做,当我的球员被击中时,我的健康棒会失去一颗心

我的健康栏脚本

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;
                }
            }

        }
    }
}

我的播放器脚本

/// <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"); 
    } 

}

和我的播放器的健康脚本

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
            }
        }
    }
}

2 个答案:

答案 0 :(得分:5)

使用Unity 4.6中的新UI系统,可以轻松创建健康栏。

  • GameObject-&gt; UI-&gt;图片
  • 将健康栏精灵放入图片中。
  • 将图像类型更改为已填充。然后您可以使用填充金额属性并通过代码控制

答案 1 :(得分:1)

PlayerScript中,使用以下代码检索HealthScript

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

如果你想在Health脚本上调用方法,你会做类似的事情。

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

这假设所有3个脚本都在同一个Game对象上。