我制作了两个脚本。它可以跟踪玩家的健康状况,健康状况栏,并在玩家损坏时使屏幕闪烁。其他脚本应放置在我希望对玩家造成伤害的任何物体上(接触时)。我的问题是,似乎什么都没有对播放器造成任何损害。
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。
答案 0 :(得分:1)
确保玩家Collider
启用了isTrigger
。
attackDamage
是公共的->在检查器中设置。确保它不是0
。
您可以使用
[Range(1,100)] public int attackDamage = 10;
自动将值固定在检查器中。
一个猜测,但我想说您的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();
}
}
您有
private void Update()
{
damaged = false;
}
public void TakeDamage(int amount)
{
damaged = true;
currentHealth -= amount;
healthSlider.value = currentHealth;
}
我不知道在TakeDamage
上还会发生什么,但是damaged
的值在Update
中被重设,因此在Trigger
设置之后,因为物理像OnTriggerEnter
这样的事件在Update
(see execution Order)之前执行。
提示:代替
player = GameObject.FindGameObjectWithTag("Player");
playerHealth = player.GetComponent<PlayerHealth>();
您也可以使用
playerHealth = FindObjectOfType<PlayerHealth>();
如果该组件在您的场景中仅存在一次。
或者为了更加灵活(拥有多个播放器),您所要做的就是将OnTriggerEnter2D
和Attack
方法更改为
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);
}
}
因此您无需先获取参考。