实际上并不需要您的循环,当有东西进入触发器时会调用 OnTriggerEnter2D()。在这种情况下,您是在告诉您的循环在您的对象进入触发器后执行两次。
要快速解决这个问题,你应该改变:
if(kill.gameObject.tag == "cage") {
for(hitCage = 0; hitCage > 2; hitCage++) {
if(hitCage > 2) {
Destroy(cage);
}
}
}
到...(未经测试)
if(kill.gameObject.tag == "cage") {
hitCage++;
if(hitCage >= 2) {
Destroy(cage);
}
}
如果您想对您似乎采用的结构提出一些建设性的批评,请阅读下文。如果您正在寻找快速解决方案,请不要太担心,但随着您的类和对象数量的增加,您可能会发现它很有用。
看来你正试图让这个班级管理所有的伤害和杀戮。更好的方法是给敌人一个生命计数器,给笼子一个生命计数器。给他们两个公共函数,比如“takeDamage(damage:int)”。那么你给我们上的这门课可能是子弹或剑之类的。这意味着您的剑(例如)将有一个名为“attackDamage”之类的变量。然后在你的剑类中,你会拥有这个 OnTriggerEnter2D() ,它会拾取进入触发器的对象,并调用类似enemy.takeDamage(attackDamage) 的东西。
然后在你的敌人或笼子类中,你需要的 takeDamage 将是在每次受到伤害时检查它是否会将其击倒到 0 生命值。如果是这样,那么它将被销毁。
这是一些示例代码(未经测试,我通常使用 C# 工作,因此如果我的函数名称错误,您可能需要稍微修改一两行)。
你的敌人和笼子类中会有这个:
var health:int;
function Start () {
health = 1;
}
function TakeDamage(damage:int) {
//check we're not passing in a value of 0 or below
if(damage > 0) {
health = health - damage;
}
//If the enemy health is now 0
if(health <= 0) {
//Destroy the enemy
Destroy(this);
}
}
所以现在你的敌人类和笼子都有 TakeDamage() 这个函数,他们现在负责杀死自己并受到伤害。这可能会更好,因为这意味着您可以拥有一个基类,例如“AttackableEntity”,其中包含 TakeDamage(),然后您想要成为可攻击的每个对象或类都会有这个(有更好的方法来构建这种继承系统)。
剑/子弹(等)类:
var attackDamage:int;
function Start() {
attackDamage = 1;
}
function OnTriggerEnter2D(collider:Collider2D) {
//get the gameObject that collided with us
var theCollidedObject:GameObject = collider.transform.gameObject;
if(theCollidedObject.gameObject.tag == "enemy") {
//Get the Enemy script attached to the gameObject so that we can use TakeDamage()
var enemy:Enemy = theCollidedObject.GetComponent<Enemy>();
//make the enemy take damage equal to this objects attackDamage
enemy.TakeDamage(attackDamage);
}
if(theCollidedObject.gameObject.tag == "cage") {
var cage:Cage = theCollidedObject.GetComponent<Cage>();
cage.TakeDamage(attackDamage);
}
}
现在你正在攻击的职业只负责找到它被击中的东西,并告诉它受到等于它的攻击伤害的伤害。
这可能会更好一些,因为它更清晰,这意味着如果你有多个敌人,他们的行为都不同,他们管理自己的生命值,而不是你的剑类必须管理敌人的所有生命值。
它还应该解决您在销毁笼子之前尝试将笼子减 2 的问题。