首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Unity2D近战战斗

Unity2D近战战斗
EN

Stack Overflow用户
提问于 2022-07-27 11:43:08
回答 2查看 80关注 0票数 0

我对编程和C#很陌生。我正试图为我的平台游戏建立一个近战系统,以下是yt的教程。

这是我的PlayerAttack脚本:

代码语言:javascript
复制
using System.Collections; using System.Collections.Generic; using UnityEngine;

public class PlayerAttack : MonoBehaviour {
    //[SerializeField] private float attackCooldown;
    [SerializeField] private float range;
    [SerializeField] private int damage;

    [SerializeField] private LayerMask enemyLayer;


    public Transform AttackPoint;

    //private float cooldownTimer = Mathf.Infinity;

    private Animator anim;
    private Enemy enemyHealth;




    private void Awake()
    {
        anim = GetComponent<Animator>();
        enemyHealth = GetComponent<Enemy>();
    }

    private void Update()
    {
        if (Input.GetButtonDown("Fire1"))
        {
            anim.SetTrigger("Attack");
            Attack();
            Debug.Log("attacking");
        }
    }

    private void OnDrawGizmos()
    {
        if (AttackPoint == null)
            return;

        Gizmos.color = Color.red;
        Gizmos.DrawWireSphere(AttackPoint.position, range);

    }



    void Attack()
    {


        Collider2D[] hitEnemies = Physics2D.OverlapCircleAll(AttackPoint.position, range, enemyLayer);

        foreach (Collider2D Enemy in hitEnemies)
        {

            Enemy.transform.GetComponent<Enemy>().TakeDamage(damage);   

        }



    }

}

这个是EnemyHealth脚本

代码语言:javascript
复制
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Enemy : MonoBehaviour
{
    [SerializeField] private int startingHealth;

    public int currentHealth;
    public Animator anim;

    void Start()
    {
        currentHealth = startingHealth;
    }

    public void TakeDamage(int _damage)
    {
        currentHealth = Mathf.Clamp(currentHealth - _damage, 0, startingHealth);

        if (currentHealth > 0)
        {
            //hurt animation
            //invulnerability
        }

        else
        {
            //die animation
            GetComponentInParent<EnemyPatrol>().enabled = false;
            GetComponent<EnemyMelee>().enabled = false;
        }


    }

    void Die()
    {
        if (currentHealth <= 0)
        {

            Debug.Log("Enemy Dead!");
            Destroy(gameObject);
            //die animation
        }


    }
}

我从PlayerAttack第61行中的Unity (对象引用未设置为对象实例)获得了一个错误:在这里输入代码

Enemy.transform.GetComponent().TakeDamage(damage);

我检查了脚本名,它们很好,我还检查了是否在编辑器中遗漏了什么,我不知道出了什么问题。

当我击中敌人时,游戏崩溃了,我得到了这个错误。谢谢

EN

回答 2

Stack Overflow用户

发布于 2022-07-27 12:02:12

您正在尝试在所有有对撞机的东西上调用Enemy.transform.GetComponent<Enemy>().TakeDamage(damage);,但是其中一些对象没有Enemy组件,所以不能在它们上调用TakeDamage。这就是错误的来源。要修复它,你必须只找到敌人的游戏对象。要做到这一点,您可以对敌人进行分配标签,并通过如下脚本检查带有Enemy标记的敌人:

代码语言:javascript
复制
  foreach (Collider2D Enemy in hitEnemies)
        {
          if (Enemy.tag == "Enemy")
            Enemy.transform.GetComponent<Enemy>().TakeDamage(damage);               
        }

还有一种没有标记的方法,我不建议这样做:

代码语言:javascript
复制
  foreach (Collider2D Enemy in hitEnemies)
        {
          if (Enemy.transform.GetComponent<Enemy>() != null)
            Enemy.transform.GetComponent<Enemy>().TakeDamage(damage);             
        }
票数 0
EN

Stack Overflow用户

发布于 2022-07-27 12:04:11

检查玩家是否击中了敌人:

代码语言:javascript
复制
foreach (Collider2D hitEnemy in hitEnemies) {
    if(hitEnemy.TryGetComponent(out Enemy enemy)) {
        enemy.TakeDamage(damage);
    }
}

,而不是答案:

在您的PlayerAttack.cs脚本中,您有一个字段enemyHealth,您试图在Awake()方法中使用enemyHealth = GetComponent<Enemy>();获取对它的引用。这没有得到对它的引用,因为Enemy.cs和PlayerAttack.cs脚本被附加到不同的游戏对象。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73137300

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档