Unity 使用接口,可以使许多不同的类可损坏,而不太需要更改造成损坏的方式,要制作基本的损坏体系,则需创建一个包含损坏功能的新可损坏界面。

在下示例中,损坏函数采用整数参数,以允许损坏目标对象传递或多或少的损坏。
public interface IDamageable
{
void Damage(int damageTaken);
}
然后,要创建一个可以损坏的目标对象,只需实现 IDamageable 接口和一个损坏函数即可。
public class Player : MonoBehaviour, IDamageable
{
[SerializeField] int health = 100;
public void Damage(int damage)
{
health -= damage;
// 播放器损坏!
if (health <= 0)
{
Destroy(gameObject);
// 重新开始游戏
}
}
}
或者在易损坏的物体上。
public class Box : MonoBehaviour, IDamageable
{
[SerializeField] int health = 25;
public void Damage(int damage)
{
health -= damage;
// 盒子被损坏了!
if (health <= 0)
{
Destroy(gameObject);
// 丢掉一些对象
}
}
}
然后,当想尝试破坏一个对象时,可以简单地搜索任何实现 IDamageable 接口的类。
public class Explosion : MonoBehaviour
{
[SerializeField] int explosionDamage = 50;
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.TryGetComponent(out IDamageable damageableObject))
{
damageableObject.Damage(explosionDamage);
}
}
}
损坏系统可能非常适合接口,因为它一般情况下涉及对许多不同类型的类执行相同类型的通用操作。
但是,这种方法存在一个问题。
接口的好处是每个实现脚本可以以不同的方式解释相同的功能,但是,当多个类出于类似的原因使用相同的接口时,最终可能会重复代码。
例如…
在上面的可损坏示例中,即使两个损坏函数中的每一个最终做不同的事情,部分损坏函数仍然被复制,特别是移除对象生命值的部分,以基本相同的方式,在两者中脚本。
一般情况下这样是不好的,如果想更改在对象损坏时移除健康的方式,需要在两个不同的地方进行,随着项目变得越来越大,可能难以管理。
因而接口的目的是允许一个类与不同类型的类进行交互,但是以一种通用的方式。它们创建抽象,通过将类是什么与它可以做什么分开,从而更容易匿名地将脚本连接在一起。
可是接口不能解决所有问题,有时使用接口而不是其他东西,可能比它的价值更麻烦。