【问题标题】:How to send an event/message to an unrelated game object in Unity/C#?如何在 Unity/C# 中向不相关的游戏对象发送事件/消息?
【发布时间】:2023-02-08 15:36:32
【问题描述】:

假设我有两个实体,一个玩家和一个敌人。他们每个人都有自己的 C# 脚本。在 Enemy 上,它有这个基本的健康管理器代码:

[SerializeField] float health = 3;

public void TakeDamage(float damage)
{
    health -= damage;

    if (health <= 0) {
        Destroy(gameObject);
        // SOME EVENT HERE?
    }
}

我想要的是让玩家知道他已经杀死了敌人(以及知道他摧毁了哪个敌人)。但是,我不确定该怎么做。我看过几种方法:

  • 动作/委托;他们会要求玩家“导入”敌人的公共行动/委托(如果我理解正确的话;我还是 C# 的新手),我不希望这两件事之间存在依赖关系……他们re 在概念上无关;我不应该在播放器上从敌人“导入”。
  • 使用 Unity 事件(如您在 UI 中配置的事件,例如按钮 OnClick());这也行不通,因为 Player 和 Enemy 都可能在运行时实例化,而不是预定义。

在我的脑海中,我想象 Player 脚本会像这样监听事件:

void OnEnemyDestroyed(GameObject enemy) { ...do things in reaction to enemy death here... }

这可能吗?

【问题讨论】:

    标签: c# unity3d


    【解决方案1】:

    对于这种特定情况,我的建议是使用接口。例如:

    public interface IUnit
    {
        void OnEnemyKilled(IUnit enemy);
    }
    

    玩家脚本和敌人脚本都会实现这个接口,TakeDamage方法还需要附加一个类型为IUnit的新参数。

    class Enemy : IUnit
    {
        public void TakeDamage(float damage, IUnit attacker = null)
        {
            health -= damage;
    
            if (health <= 0) {
                attacker?.OnEnemyKilled(this);
                Destroy(gameObject);
            }
        }
    
        public void OnEnemyKilled(IUnit enemy){}
    }
    

    这种做法不仅解决了问题,好处是在某些时候,单一的伤害值是不够的,你可能需要知道是谁发起了这次攻击,然后你可以在接口中添加额外的方法并在@987654325中执行@.

    请注意,您最好预先设置回调,以便您可以在其中继续访问被杀死实体的所有属性。

    【讨论】:

    • 如果其中一个实体成为一个单元(并因此继承 IUnit)没有意义怎么办?例如,打砖块式的球和积木情况
    猜你喜欢
    • 2018-01-06
    • 1970-01-01
    • 1970-01-01
    • 2010-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-04
    • 2022-01-23
    相关资源
    最近更新 更多