使玩家在Unity 2D中受到伤害

时间:2018-11-14 06:00:13

标签: c# unity3d

我制作了两个脚本。它可以跟踪玩家的健康状况,健康状况栏,并在玩家损坏时使屏幕闪烁。其他脚本应放置在我希望对玩家造成伤害的任何物体上(接触时)。我的问题是,似乎什么都没有对播放器造成任何损害。

PlayerHealth.cs:

    
using UnityEngine;
using UnityEngine.UI;

public class PlayerHealth : MonoBehaviour
{
    public int currentHealth;
    public float flashSpeed = 5;
    public Slider healthSlider;
    public Color flashColour = new Color(1, 0, 0, 0.1f);
    bool isDead;
    bool damaged;

    private void Awake()
    {
        currentHealth = 100;
    }

    private void Update()
    {
        damaged = false;
    }

    public void TakeDamage(int amount)
    {
        damaged = true;
        currentHealth -= amount;
        healthSlider.value = currentHealth;
    }
}

AttackPlayer.cs:

using UnityEngine;

public class AttackPlayer : MonoBehaviour
{
    public float timeBetweenAttacks = 0.5f;
    public int attackDamage = 10;

    GameObject player;
    PlayerHealth playerHealth;

    float timer;

    private void Awake()
    {
        player = GameObject.FindGameObjectWithTag("Player");
        playerHealth = player.GetComponent<PlayerHealth>();
    }

    private void OnTriggerEnter2D(Collider2D col)
    {
        if (col.gameObject == player)
        {
            Attack();
        }
    }

    private void Update()
    {
        timer += Time.deltaTime;

        if(playerHealth.currentHealth <=0)
        {
            // TODO: add death script here.
        }
    }

    void Attack()
    {
        timer = 0f;
        if(playerHealth.currentHealth > 0)
        {
            playerHealth.TakeDamage(attackDamage);
        }
    }
}

播放器具有刚体2D。播放器和损坏的对象上面都有Box Collider 2D。

1 个答案:

答案 0 :(得分:1)

  1. 确保玩家Collider启用了isTrigger

  2. attackDamage是公共的->在检查器中设置。确保它不是0

    您可以使用

    [Range(1,100)] public int attackDamage = 10;
    

    自动将值固定在检查器中。

  3. 一个猜测,但我想说您的Collider可能不在GameObject player上,但可能在其子级之一上=>条件col.gameObject == player不成立。

    代替GameObject引用,而是像这样比较PlayerHealth(因为只有一个)引用

    private void OnTriggerEnter2D(Collider2D col)
    {
        // gets PlayerHealth component on this or any parent object
        var health = col.GetComponentInParent<PlayerHealth>();
        if (health  == playerHealth)
        {
            Attack();
        }
    }
    
  4. 您有

    private void Update()
    {
        damaged = false;
    }
    
    public void TakeDamage(int amount)
    {
        damaged = true;
        currentHealth -= amount;
        healthSlider.value = currentHealth;
    }
    

    我不知道在TakeDamage上还会发生什么,但是damaged的值在Update中被重设,因此在Trigger设置之后,因为物理像OnTriggerEnter这样的事件在Updatesee execution Order)之前执行。


提示:代替

player = GameObject.FindGameObjectWithTag("Player");
playerHealth = player.GetComponent<PlayerHealth>();

您也可以使用

playerHealth = FindObjectOfType<PlayerHealth>();

如果该组件在您的场景中仅存在一次。


或者为了更加灵活(拥有多个播放器),您所要做的就是将OnTriggerEnter2DAttack方法更改为

private void OnTriggerEnter2D(Collider2D col)
{
    // gets PlayerHealth component on this or any parent object
    var health = col.GetComponentInParent<PlayerHealth>();
    if (health != null)
    {
        Attack(health);
    }
}

void Attack(PlayerHealth health)
{
    timer = 0f;
    if(health.currentHealth > 0)
    {
        health.TakeDamage(attackDamage);
    }
}

因此您无需先获取参考。