简体   繁体   English

Unity3D:当敌人(克隆)被击中时,原来的预制敌人受到伤害而不是克隆?

[英]Unity3D: When the enemy (clones) are hit, the original prefab enemy takes damage and not the clones?

The clones spawn with an EnemyHealth script where their health parameters are set.克隆生成时带有设置健康参数的 EnemyHealth 脚本。 Within in this script is a function called TakeDamage().在这个脚本中是一个名为 TakeDamage() 的 function。 My only guess is that I'm not explicitly defining which enemy needs to have it's health drained within TakeDamage() but I'm having some trouble wrapping my head around that because each clone has its own health and TakeDamage() is called from my PlayerAttack script when the weapon collides with the enemy, so I was assuming it would only happen to the colliding enemy.我唯一的猜测是,我没有明确定义哪个敌人需要在 TakeDamage() 中耗尽其生命值,但我在解决这个问题时遇到了一些麻烦,因为每个克隆都有自己的生命值,并且 TakeDamage() 是从我的当武器与敌人碰撞时的 PlayerAttack 脚本,所以我假设它只会发生在碰撞的敌人身上。 But I guess I need a defined way for TakeDamage() to only affect the enemy that's involved with the collision.但我想我需要一个明确的方式让 TakeDamage() 只影响与碰撞有关的敌人。

I'm self taught so I apologize if this is simple or a poor question, I've searched all over the place for several days now so I hope someone can help!我是自学成才的,所以如果这是一个简单或糟糕的问题,我深表歉意,我已经在这个地方搜索了几天,所以我希望有人能提供帮助!


EnemyHealth Script: EnemyHealth 脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerAttack : MonoBehaviour
{
    public EnemyHealth enemyHealth;
    public Animator animator;
    public LayerMask enemyLayers;
    public bool allowDamage = false;

    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            clickAttack();
        }
    }

    private void AnimationCheck()
    {
        if (animator.GetCurrentAnimatorStateInfo(0).IsName("Stab"))
        {
            allowDamage = true;
        }
        else
        {
            allowDamage = false;
        }
    }
    private void clickAttack()
    {
        animator.SetTrigger("Attacking");
    }

    void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.CompareTag("Enemy"))
        {
            AnimationCheck();
            if (allowDamage == true)
            {
                enemyHealth.TakeDamage();
            }

        }
    }
}

PlayerAttack Script:玩家攻击脚本:

 using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerAttack: MonoBehaviour { public EnemyHealth enemyHealth; public Animator animator; public LayerMask enemyLayers; public bool allowDamage = false; // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { if (Input.GetMouseButtonDown(0)) { clickAttack(); } } private void AnimationCheck() { if (animator.GetCurrentAnimatorStateInfo(0).IsName("Stab")) { allowDamage = true; } else { allowDamage = false; } } private void clickAttack() { animator.SetTrigger("Attacking"); } void OnCollisionEnter(Collision collision) { if (collision.gameObject.CompareTag("Enemy")) { AnimationCheck(); if (allowDamage == true) { enemyHealth.TakeDamage(); } } } }

Screenshot of Unity Scene: Unity 场景截图:
在此处输入图像描述

Clone marked in blue is the one being hit, enemy marked in yellow is the original that's taking damage when other enemies are being hit.蓝色标记的克隆是被击中的,黄色标记的敌人是在其他敌人被击中时受到伤害的原始敌人。

The reason only one enemy is taking damage is because you are referencing one enemies health component.只有一个敌人受到伤害的原因是因为你引用了一个敌人的健康成分。 Whatever enemy you assign in the inspector to your enemyHealth variable is the one that will take damage.无论您在检查器中为enemyHealth变量分配什么敌人,都会受到伤害。

Remove the enemyHealth variable from your PlayerAttack class.从您的 PlayerAttack class 中删除enemyHealth 变量。

Inside of the collision function, you will get the enemyHealth from the object that you collided with.在碰撞 function 内部,你会从你碰撞的 object 中获得敌人的生命值。

void OnCollisionEnter(Collision collision)
{
    if (collision.gameObject.CompareTag("Enemy"))
    {
        AnimationCheck();

        if (allowDamage)
        {
            var enemyHealth = collision.gameObject.GetComponent<EnemyHealth>();
            if (enemyHealth)
            {
                enemyHealth.TakeDamage();
            }
        }
    }
}

You can potentially get rid of the CompareTag line if only enemies will have the EnemyHealth script (which it sounds like is the case).如果只有敌人会有 EnemyHealth 脚本(听起来就是这种情况),您可能会摆脱 CompareTag 行。 Then you only need to check if the gameObject you collided with has that script to know it is an enemy.然后你只需要检查你碰撞的游戏对象是否有那个脚本就知道它是一个敌人。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM