团结生存射击游戏中没有任何伤害

时间:2016-03-16 02:14:39

标签: c# unity3d unity5

我一直在关注Unity提供的Shooter Survival教程。我一直在使用它来理解某些代码位如何与c#中的不同脚本中的相互作用和相互调用。最近我遇到了一个问题,我没有从敌人的攻击中受到伤害;我仍然可以伤害他们。

我的玩家健康代码

using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using UnityEngine.SceneManagement;

namespace CompleteProject
{
public class PlayerHealth : MonoBehaviour
{

public int startingHealth = 100;                            // The amount of health the player starts the game with.
    public int currentHealth;                                   // The current health the player has.
    public Slider healthSlider;                                 // Reference to the UI's health bar.
    public Image damageImage;                                   // Reference to an image to flash on the screen on being hurt.
    public AudioClip deathClip;                                 // The audio clip to play when the player dies.
    public float flashSpeed = 5f;                               // The speed the damageImage will fade at.
    public Color flashColour = new Color(1f, 0f, 0f, 0.1f);     // The colour the damageImage is set to, to flash.

    Animator anim;                                              // Reference to the Animator component.
    AudioSource playerAudio;                                    // Reference to the AudioSource component.
    PlayerMovement playerMovement;                              // Reference to the player's movement.
    PlayerShooting playerShooting;                              // Reference to the PlayerShooting script.
    bool isDead;                                                // Whether the player is dead.
    bool damaged;                                               // True when the player gets damaged.


    void Awake ()

    {
        // Setting up the references.
        anim = GetComponent <Animator> ();
        playerAudio = GetComponent <AudioSource> ();
        playerMovement = GetComponent <PlayerMovement> ();
        playerShooting = GetComponentInChildren <PlayerShooting> ();

        // Set the initial health of the player.
        currentHealth = startingHealth;
    }


    void Update ()
    {
        // If the player has just been damaged...
        if(damaged)
        {
            // ... set the colour of the damageImage to the flash colour.
            damageImage.color = flashColour;
        }
        // Otherwise...
        else
        {
            // ... transition the colour back to clear.
            damageImage.color = Color.Lerp (damageImage.color, Color.clear, flashSpeed * Time.deltaTime);
        }

        // Reset the damaged flag.
        damaged = false;
    }


    public void TakeDamage (int amount)
    {
        // Set the damaged flag so the screen will flash.
        damaged = true;

        // Reduce the current health by the damage amount.
        currentHealth -= amount;

        // Set the health bar's value to the current health.
        healthSlider.value = currentHealth;

        // Play the hurt sound effect.
        playerAudio.Play ();

        // If the player has lost all it's health and the death flag hasn't been set yet...
        if(currentHealth <= 0 && !isDead)
        {
            // ... it should die.
            Death ();
        }
    }


    void Death ()
    {
        // Set the death flag so this function won't be called again.
        isDead = true;

        // Turn off any remaining shooting effects.
        playerShooting.DisableEffects ();

        // Tell the animator that the player is dead.
        anim.SetTrigger ("Die");

        // Set the audiosource to play the death clip and play it (this will stop the hurt sound from playing).
        playerAudio.clip = deathClip;
        playerAudio.Play ();

        // Turn off the movement and shooting scripts.
        playerMovement.enabled = false;
        playerShooting.enabled = false;
    }


    public void RestartLevel ()
    {
        // Reload the level that is currently loaded.
        SceneManager.LoadScene (0);
    }
}
}

我的敌人攻击代码

using UnityEngine;
using System.Collections;

namespace CompleteProject
{
public class EnemyAttack : MonoBehaviour
{
    public float timeBetweenAttacks = 0.5f;     // The time in seconds between each attack.
    public int attackDamage = 10;               // The amount of health taken away per attack.


    Animator anim;                              // Reference to the animator component.
    GameObject player;                          // Reference to the player GameObject.
    PlayerHealth playerHealth;                  // Reference to the player's health.
    EnemyHealth enemyHealth;                    // Reference to this enemy's health.
    bool playerInRange;                         // Whether player is within the trigger collider and can be attacked.
    float timer;                                // Timer for counting up to the next attack.


    void Awake ()
    {
        // Setting up the references.
        player = GameObject.FindGameObjectWithTag ("Player");
        playerHealth = player.GetComponent <PlayerHealth> ();
        enemyHealth = GetComponent<EnemyHealth>();
        anim = GetComponent <Animator> ();
    }


    void OnTriggerEnter (Collider other)
    {
        // If the entering collider is the player...
        if(other.gameObject == player)
        {
            // ... the player is in range.
            playerInRange = true;
        }
    }


    void OnTriggerExit (Collider other)
    {
        // If the exiting collider is the player...
        if(other.gameObject == player)
        {
            // ... the player is no longer in range.
            playerInRange = false;
        }
    }


    void Update ()
    {
        // Add the time since Update was last called to the timer.
        timer += Time.deltaTime;

        // If the timer exceeds the time between attacks, the player is in range and this enemy is alive...
        if(timer >= timeBetweenAttacks && playerInRange && enemyHealth.currentHealth > 0)
        {
            // ... attack.
            Attack ();
        }

        // If the player has zero or less health...
        if(playerHealth.currentHealth <= 0)
        {
            // ... tell the animator the player is dead.
            anim.SetTrigger ("PlayerDead");
        }
    }


    void Attack ()
    {
        // Reset the timer.
        timer = 0f;

        // If the player has health to lose...
        if(playerHealth.currentHealth > 0)
        {
            // ... damage the player.
            playerHealth.TakeDamage (attackDamage);
        }
    }
}
}

我的一位朋友告诉我使用C ++,他发现奇怪的是,在播放器层次结构中,播放器健康是一种资产,可能必须以某种方式直接调用。

Screen shot of Player hierarchy

2 个答案:

答案 0 :(得分:0)

问题可能在这里:

if(timer >= timeBetweenAttacks && playerInRange && enemyHealth.currentHealth > 0)
  {
   // ... attack.
   Attack ();
  }

对于被敌人攻击的玩家来说,三件事情必须同时成真。 timer必须 或等于 0.5f playerInRange也必须是true。最后enemyHealth.currentHealth必须超过 0

一旦您的代码超过 30 ,包含太多C#脚本,必须知道如何调试您自己的代码。

我最好的猜测是playerInRange永远不会true,这就是为什么攻击而不是被调用的原因。在Debug.Log("Attacked Player");之前添加Attack ();,然后检查&#34; 已攻击玩家&#34;当敌人攻击玩家时显示。如果不是,那么其中一个是false

同时添加Debug.Log("Player is in Range");以查看是否正在检测播放器 void OnTriggerEnter (Collider other);功能如下:

   void OnTriggerEnter (Collider other)
    {
        // If the entering collider is the player...
        if(other.gameObject == player)
        {
            // ... the player is in range.
            playerInRange = true;
            Debug.Log("Player is in Range");
        }
    }

这些将告诉你场景中发生了什么。

答案 1 :(得分:0)

我可以确认代码是否按您提供的方式运行,但需要一组特定情况才能EnemyAttack成功调用PlayerHealth.TakeDamage()

  • 您的EnemyAttack所附加的GameObject需要Rigidbody,您可能需要设置 IsKinematic = true
  • 任何类型的Collider组件 - 标有 IsTrigger = true
  • PlayerHealth所附加的GameObject需要RigidbodyCollider,其中Gameobject的标记设置为&#39;播放器&#39;,因为您&# 39;已经在你提供的屏幕上证明了

我相信您的EnemyAttack未能损坏播放器,因为标记playerInRange始终为false。通过OnTriggerEnter()但不是OnTriggerExit()之前,此标志设置为true。由于组件未在场景中正确设置,因此永远不会调用OnTriggerEnter()