当前位置:  开发笔记 > 编程语言 > 正文

代表和事件在特定实例上触发

如何解决《代表和事件在特定实例上触发》经验,为你挑选了1个好方法。

我有以下定义事件和委托的类。然后,我有一种触发事件的方法,如下所示:

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,而不仅仅是我正在使用的实例。



1> Everts..:

您似乎在滥用案例中的事件模式。事件/侦听器的要点是,无论谁在侦听,发送方都会发送信息。

但是在您的情况下,发件人针对的是一个特定的实例,您实际上已经对其进行了引用。然后,您还可以获取该对象的组件并在其上调用一个方法。

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 EventHandler  RaiseDeathEvent;
     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或场景管理器等其他项目通知死亡,以便他们可以执行操作,则可以让他们找到事件并注册。玩家甚至都不知道它们。

推荐阅读
coco2冰冰
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有