我有以下定义事件和委托的类。然后,我有一种触发事件的方法,如下所示:
public class HealthManager : MonoBehaviour { // Create the delegate public delegate void ObjectDeath(GameObject go); // Create the event public static event ObjectDeath OnObjectDeath; public static void GiveDamage(GameObject dealer, GameObject receiver, float amount){ /* Subtract health here ... Code Snipped ... */ if(objectHealth.health <= objectHealth.deathHealth){ // Trigger the delegate/event OnObjectDeath(receiver); } } }
然后,我有一个此类监听事件的类,如下所示:
public class DeathListener : MonoBehaviour { // Add event listeners when object gets enabled void OnEnable () { HealthManager.OnObjectDeath += Died; } // Remove event listeners when object gets disabled void OnDisable () { HealthManager.OnObjectDeath -= Died; } void Died(GameObject go){ if(gameObject == go){ Destroy(gameObject); } } }
我的问题是,是否可以仅在特定对象上触发事件?
因此,不要这样做:
// Trigger OnObjectDeath(receiver); // ---------------------------- // void Died(GameObject go){ if(gameObject == go){ Destroy(gameObject); } }
我可以做这样的事情:
receiver.OnObjectDeath(); // ---------------------------- // void Died(){ Destroy(gameObject); }
我希望有一种方法,在这种情况下,Died
我不必检查要在哪个对象上应用它。目前,如果我删除该if
语句,那么它将应用于所有gameObjects,而不仅仅是我正在使用的实例。
您似乎在滥用案例中的事件模式。事件/侦听器的要点是,无论谁在侦听,发送方都会发送信息。
但是在您的情况下,发件人针对的是一个特定的实例,您实际上已经对其进行了引用。然后,您还可以获取该对象的组件并在其上调用一个方法。
public static void GiveDamage(GameObject dealer, GameObject receiver, float amount){ /* Subtract health here ... Code Snipped ... */ if(objectHealth.health <= objectHealth.deathHealth){ // Trigger the delegate/event receiver.GetComponent< DeathListener >().Died(); // no need for parameter } }
编辑:根据您的评论,一种更合适的方法(以我的观点)将是使用Damage方法具有IDamageable接口。然后,所有应损坏的物品都应实施该方法,以使它们正确损坏。然后,您可以简单地调用带有损坏程度的Damage方法,并在需要时处理死亡。
让我们考虑一个子弹系统:
public void Bullet:MonoBehaviour{ public int damage = 10; // it is hitting either from raycast or collision or else void OnHit(GameObject collidedObject){ IDamageable dam = collidedObject.GetComponent(); // if you hit a wall or no damageable item, it will be false if(dam != null) { dam.Damage(damage); } } }
子弹忽略了它所击中的东西,应该不在乎。只重要的是它应该损坏多少。
public class Player : MonoBehaviour , IDamageable{ int health = 20; public EventHandlerRaiseDeathEvent; protected void OnDeath(EventArgs arg){ if(RaiseDeathEvent != null) RaiseDeathEvent(this, arg); } public void Damage(int damage){ this.health -= damage; if(this.health < 0){ Died(); OnDeath(null); } } }
妳去 如果需要将UI或场景管理器等其他项目通知死亡,以便他们可以执行操作,则可以让他们找到事件并注册。玩家甚至都不知道它们。