【问题标题】:I'm having trouble using this function to lower the damage of the enemies in my game我无法使用此功能降低游戏中敌人的伤害
【发布时间】:2020-02-04 09:26:50
【问题描述】:

所以,我创建了一个函数来存储子弹与敌人相撞时发生的情况。

public void Hit(Collider other, bool enemyInstanceTag, int enemyLife, int enemyKillPoint)
{
    if (other.gameObject.CompareTag("PistolBullet") && enemyInstanceTag)
    {
        enemyLife -= player.damage;
        player.score += enemyKillPoint;
        Destroy(other.gameObject);
    }
}

当我尝试使用它时:

private void OnTriggerEnter(Collider other)
    {
        Hit(other, gameObject.CompareTag("ERunner"), enemyRunner.life, enemyRunner.killPoint);
    }

在每次击中时,生命值都会恢复到完全生命值。想象敌人的生命值是 2,当我击中它时它会降低到 1,但在下一次攻击中又从 2 开始。

但如果我运行它,健康状况良好:

private void OnTriggerEnter(Collider other)
{

    if (other.gameObject.CompareTag("PistolBullet") && gameObject.CompareTag("ERunner"))
    {
        enemyRunner.life -= player.damage;
        player.score += enemyRunner.killPoint;
        Destroy(other.gameObject);
    }
}

问题是我有多个敌人,我不想重复相同的代码行,所以我想创建一个函数。

提前致谢。

【问题讨论】:

    标签: c# function unity3d


    【解决方案1】:

    Int 是按值传递的,因此enemyLife 参数是一个临时副本。随心所欲地改变它,但是一旦你不改变对象的enemyLife,你就是在改变一个副本。

    修复:传入一个敌方物体。也就是说,如果您操作对象,则更改是永久性的。

    所以,enemy.life -= player.damage 应该可以解决问题。

    编辑:

    更改呼叫来源:

    private void OnTriggerEnter(Collider other)
        {
            Hit(other, gameObject.CompareTag("ERunner"), enemyRunner.life, enemyRunner.killPoint);
        }
    

    private void OnTriggerEnter(Collider other)
        {
            Hit(other, gameObject.CompareTag("ERunner"), enemyRunner );
        }
    

    然后,将 HIT 方法更改为

    public void Hit(Collider other, bool enemyInstanceTag, [Enemy Type or Interface] enemy)
    {
        if (other.gameObject.CompareTag("PistolBullet") && enemyInstanceTag)
        {
            enemy.life -= player.damage;
            player.score += enemy.KillPoint;
            Destroy(other.gameObject);
        }
    }
    

    我无法从贴的代码中判断敌人的类型,所以我把[敌人类型或接口]放在那里

    进一步编辑——如何使这项工作适用于所有敌人类型:

    创建接口

    public interface iHittable{
        public int DoDamage(int damage)
    }
    

    现在你的敌人都将拥有

    public Class TieFighter : iHittable{
    // lots of code
    
    // important bit
    
    public int DoDamage(int damage) // from iHittable
    {
       this.life -= damage;
       return this.PointsForDamage;  //  could be another method that calculates points, or a field if points are constant.  
    }
    }
    

    现在我们也可以这样做:

    public Class UssEnterprise : iHittable{
    {
        public int DoDamage(int damage) // from iHittable
        {
            if (sheildLevel > 0)
            {
                sheildLevel -= damage;
                return 0;
            } 
            else
            {
                life -= damage;
                return PointsForDamage; 
           } 
        }
    } 
    

    所以假设我们的enemyRunner 是TieFighter。命中呼叫仍将是:

        Hit(other, gameObject.CompareTag("ERunner"), enemyRunner );
    

    我们的方法是:

    public void Hit(Collider other, bool enemyInstanceTag, iHittable enemy)
    {
        if (other.gameObject.CompareTag("PistolBullet") && enemyInstanceTag)
        {
    
            player.score += enemy.DoDamage(player.damage);
            Destroy(other.gameObject);
        }
    }
    

    这里的诀窍是对象可以是许多不同的类型,根据我们调用它们的类型,我们可以依赖它们提供不同的方法。

    【讨论】:

    • 我理解,但“其他”是从玩家射出并击中敌人的子弹。我的 EnemyController 中的 life 变量是一个 int,这就是我在函数中传递一个 int 的原因。你能告诉我你将如何编写函数吗?谢谢!
    • 是的,这行得通,但我不能对多个敌人使用相同的函数,因为我只在方法中调用 ERunnerController。公共无效命中(对撞机其他,布尔enemyInstanceTag,ERunnerController敌人){如果(other.gameObject.CompareTag(“PistolBullet”)&&enemyInstanceTag){enemy.health -= player.damage; player.score += 敌人.killPoint;销毁(other.gameObject); } } 我有多个具有多个控制器的敌人,每个人都有不同的生命/健康状况。
    • 这就是我今天要做的。如果有更多兴趣,我建议阅读有关接口和多态性的内容,然后再问一个问题。
    • 这就像一个魅力!不了解接口,肯定要检查一下。感谢您的帮助!
    猜你喜欢
    • 2014-12-28
    • 2020-10-10
    • 1970-01-01
    • 2016-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多