【问题标题】:How to Make Enemy Attack When In Range of The Player? [duplicate]在玩家范围内如何使敌人攻击? [复制]
【发布时间】:2021-11-10 18:25:56
【问题描述】:

所以我的游戏是一个 2D 自上而下的运动游戏,我的脚本确实让我的敌人攻击,但它不断循环攻击动画,因为我显然不知道在玩家造成伤害而不是让他不断循环。此外,当我接近我的敌人时,我似乎遇到了一个错误,就像现在它说的那样

NullReferenceException:对象引用未设置为对象的实例 EnemyCombat.Attack () (在 Assets/EnemyCombat.cs:36) EnemyCombat.Update () (在 Assets/EnemyCombat.cs:25)

另外,这里是 EnemyCombat 脚本

    enemy attausing System.Collections;
    using System.Collections.Generic;
    using UnityEngine;

    public class EnemyCombat : MonoBehaviour
    {
        public Animator animator;

        public Transform AttackPoint;

        public float attackRange = 0.5f;

        public LayerMask enemyLayers;

        public int attackDamage = 5;

        public float attackRate = 2f;
        float nextAttackTime = 0f;

        // Update is called once per frame
        void Update()
        {
            if (Time.time >= nextAttackTime)
            {    
                Attack();
                nextAttackTime = Time.time + 1f / attackRate;    
            }
        }

        void Attack()
        {
            animator.SetTrigger("Attack");
            Collider2D[] hitEnemies = Physics2D.OverlapCircleAll(AttackPoint.position, attackRange, enemyLayers);
            foreach (Collider2D enemy in hitEnemies)
            {
                enemy.GetComponent<Enemy>().TakeDamage(attackDamage);
            }
        }

        void OnDrawGizmosSelected()
        {
            if (AttackPoint == null)
                return;

            Gizmos.DrawWireSphere(AttackPoint.position, attackRange);
        }
    }

【问题讨论】:

  • 听起来animatorAttackPointGetComponent&lt;Enemy&gt;null(我们不知道哪一行是36)...你试过Debugging your code 吗?

标签: c# unity3d


【解决方案1】:

修复你的无限攻击循环:

// Update is called once per frame
void Update()
{
    if (attackRate >= nextAttackTime) /* checks that nextAttackTime is less than or equal to the attackRate */
    {    
        Attack();
        nextAttackTime = Time.deltaTime * 5f; // adds 5 seconds to nextAttackTime   
    }
    else
    {
        nextAttackTime -= Time.deltaTime; /* if nextAttackTime is greater than the attackRate, subtract one from nextAttackTime. this only happens once per second because you use Time.deltaTime */
    }
}

【讨论】:

  • 另外,您可能希望将 nextAttackTime 重命名为 nextAttackTimer,以便在几个月后再次查看时更容易理解
【解决方案2】:

从那个 NullReference 错误看来,您遇到的主要问题是代码或游戏层次结构中没有实际点告诉您的脚本它指的是哪个游戏对象。

第 36 行正在尝试使用 .GetComponent&lt;Enemy()&gt; 检索该信息,因此您需要提供该参考。

您可以通过创建一个公共变量来相当容易地在脚本中执行此操作,您可以将敌人的游戏对象拖入 Unity 的层次结构中。

尝试类似: public GameObject enemyObject;

当您选择可以将适当的游戏对象拖入其中的脚本时,这将在层次结构中可见的脚本中创建一个变量。

可能需要对其进行一些调整,因为我看不到您的其余代码,但这似乎是问题所在。

另一种选择是尝试手动添加:

void Start()
    {
        GameObject enemyObject = gameObject.GetComponent<Enemy>();
    }

这取自Unity Scripting Documentation

【讨论】:

  • 由于某种原因,您提供的游戏对象代码没有给我空间来拖动游戏对象。我确切地知道你的意思,但由于某种原因,输入不会为游戏对象的脚本添加插槽,这可能是什么原因?
  • 这很奇怪!我敢肯定,现在你已经被激怒了。我将在我的原始帖子中添加另一个选项。这个评论部分的格式太糟糕了。
  • 让它工作!至少要伤害并伤害我的主要玩家哈哈。我的怪物仍然会每秒攻击,有什么解决办法吗?
  • GameObject enemyObject = gameObject.GetComponent&lt;GameObject&gt;(); 没有意义......这应该做什么? GameObject 不是组件,因此您不能将其用于 GetComponent ...
猜你喜欢
  • 1970-01-01
  • 2017-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-11
  • 1970-01-01
  • 2019-06-16
  • 1970-01-01
相关资源
最近更新 更多