c# - Unity Survival Shooter Enemy 不受伤害 - Android

标签 c# android unity3d

我正在尝试将 Unity Survival Shooter 游戏部署到 Android 设备。游戏运行良好,除了当我射击敌人时,它不会受到任何伤害也不会死亡。 这是我的 PlayerShooting 脚本。

using UnityEngine;
using System.Threading;
using UnityStandardAssets.CrossPlatformInput;

namespace CompleteProject
{
public class PlayerShooting : MonoBehaviour
{
    public int damagePerShot = 20;                  // The damage inflicted by each bullet.
    public float timeBetweenBullets = 0.15f;        // The time between each shot.
    public float range = 100f;                      // The distance the gun can fire.


    float timer;                                    // A timer to determine when to fire.
    Ray shootRay;                                   // A ray from the gun end forwards.
    RaycastHit shootHit;                            // A raycast hit to get information about what was hit.
    int shootableMask;                              // A layer mask so the raycast only hits things on the shootable layer.
    ParticleSystem gunParticles;                    // Reference to the particle system.
    LineRenderer gunLine;                           // Reference to the line renderer.
    AudioSource gunAudio;                           // Reference to the audio source.
    Light gunLight;                                 // Reference to the light component.
    public Light faceLight;                             // Duh
    float effectsDisplayTime = 0.2f;                // The proportion of the timeBetweenBullets that the effects will display for.
    public float timertime = 0.0f;


    void Awake ()
    {
        // Create a layer mask for the Shootable layer.
        shootableMask = LayerMask.GetMask ("Shootable");

        // Set up the references.
        gunParticles = GetComponent<ParticleSystem> ();
        gunLine = GetComponent <LineRenderer> ();
        gunAudio = GetComponent<AudioSource> ();
        gunLight = GetComponent<Light> ();
        //faceLight = GetComponentInChildren<Light> ();
    }


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

     #if !MOBILE_INPUT
        // If the Fire1 button is being press and it's time to fire...
        if(Input.GetButton ("Fire1") && timer >= timeBetweenBullets && Time.timeScale != 0)
        {
            // ... shoot the gun.
            Shoot ();
        }
       #else
        // If there is input on the shoot direction stick and it's time to fire.
        bool check = CrossPlatformInputManager.GetButtonDown("JumpButton");
        check = true;
        //Debug.Log(check);
        if(check == true)
       // if ((CrossPlatformInputManager.GetAxisRaw("Move X") != 0 || CrossPlatformInputManager.GetAxisRaw("Move Y") != 0) && timer >= timeBetweenBullets)
        {
            // ... shoot the gun
            //System.Threading.Thread.Sleep(2000);
            timertime -= Time.deltaTime;
            if(timertime < 0.0f)
            {
                Shoot();
                timertime = 0.175f;
            }
        }
        #endif
        // If the timer has exceeded the proportion of timeBetweenBullets that the effects should be displayed for...
        if(timer >= timeBetweenBullets * effectsDisplayTime)
        {
            // ... disable the effects.
            DisableEffects ();
        }
    }


    public void DisableEffects ()
    {
        // Disable the line renderer and the light.
        gunLine.enabled = false;
        faceLight.enabled = false;
        gunLight.enabled = false;
    }


    public void Shoot ()
    {
        // Reset the timer.
        Debug.Log("Inside Shoot");
        timer = 0f;

        // Play the gun shot audioclip.
        gunAudio.Play ();

        // Enable the lights.
        gunLight.enabled = true;
        faceLight.enabled = true;

        // Stop the particles from playing if they were, then start the particles.
        gunParticles.Stop ();
        gunParticles.Play ();

        // Enable the line renderer and set it's first position to be the end of the gun.
        gunLine.enabled = true;
        gunLine.SetPosition (0, transform.position);

        // Set the shootRay so that it starts at the end of the gun and points forward from the barrel.
        shootRay.origin = transform.position;
        shootRay.direction = transform.forward;

        // Perform the raycast against gameobjects on the shootable layer and if it hits something...
        Debug.Log("Going inside Physics Raycast");
        if(Physics.Raycast (shootRay, out shootHit, range, shootableMask))
        {
            // Try and find an EnemyHealth script on the gameobject hit.
            Debug.Log("Inside Physics Raycast");
            EnemyHealth enemyHealth = shootHit.collider.GetComponent <EnemyHealth> ();
            Debug.Log (enemyHealth);
            Debug.Log ("Checking if enemyHealth is not null");

            // If the EnemyHealth component exist...
            if(enemyHealth != null)
            {
                // ... the enemy should take damage.
                Debug.Log("Inside enemyHealth != null if condition");
                enemyHealth.TakeDamage (damagePerShot, shootHit.point);
            }

            // Set the second position of the line renderer to the point the raycast hit.
            gunLine.SetPosition (1, shootHit.point);
        }
        // If the raycast didn't hit anything on the shootable layer...
        else
        {
            // ... set the second position of the line renderer to the fullest extent of the gun's range.
            gunLine.SetPosition (1, shootRay.origin + shootRay.direction * range);
        }
    }
}
}

这是我的 EnemyHealth 脚本。

using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;

namespace CompleteProject
{
public class EnemyHealth : MonoBehaviour
{
    public int startingHealth = 100;            // The amount of health the enemy starts the game with.
    public int currentHealth;                   // The current health the enemy has.
    public float sinkSpeed = 2.5f;              // The speed at which the enemy sinks through the floor when dead.
    public int scoreValue = 10;                 // The amount added to the player's score when the enemy dies.
    public AudioClip deathClip;                 // The sound to play when the enemy dies.


    Animator anim;                              // Reference to the animator.
    AudioSource enemyAudio;                     // Reference to the audio source.
    ParticleSystem hitParticles;                // Reference to the particle system that plays when the enemy is damaged.
    CapsuleCollider capsuleCollider;            // Reference to the capsule collider.
    bool isDead;                                // Whether the enemy is dead.
    bool isSinking;                             // Whether the enemy has started sinking through the floor.


    void Awake ()
    {
        // Setting up the references.
        anim = GetComponent <Animator> ();
        enemyAudio = GetComponent <AudioSource> ();
        hitParticles = GetComponentInChildren <ParticleSystem> ();
        capsuleCollider = GetComponent <CapsuleCollider> ();

        // Setting the current health when the enemy first spawns.
        currentHealth = startingHealth;
    }


    void Update ()
    {
        // If the enemy should be sinking...
        if(isSinking)
        {
            // ... move the enemy down by the sinkSpeed per second.
            transform.Translate (-Vector3.up * sinkSpeed * Time.deltaTime);
        }
    }


    public void TakeDamage (int amount, Vector3 hitPoint)
    {
        // If the enemy is dead...
        if(isDead)
            // ... no need to take damage so exit the function.
            return;

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

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

        // Set the position of the particle system to where the hit was sustained.
        hitParticles.transform.position = hitPoint;

        // And play the particles.
        hitParticles.Play();

        // If the current health is less than or equal to zero...
        if(currentHealth <= 0)
        {
            // ... the enemy is dead.
            Death ();
        }
    }


    void Death ()
    {
        // The enemy is dead.
        isDead = true;

        // Turn the collider into a trigger so shots can pass through it.
        capsuleCollider.isTrigger = true;

        // Tell the animator that the enemy is dead.
        anim.SetTrigger ("Dead");

        // Change the audio clip of the audio source to the death clip and play it (this will stop the hurt clip playing).
        enemyAudio.clip = deathClip;
        enemyAudio.Play ();
    }


    public void StartSinking ()
    {
        // Find and disable the Nav Mesh Agent.
        GetComponent <UnityEngine.AI.NavMeshAgent> ().enabled = false;

        // Find the rigidbody component and make it kinematic (since we use Translate to sink the enemy).
        GetComponent <Rigidbody> ().isKinematic = true;

        // The enemy should no sink.
        isSinking = true;

        // Increase the score by the enemy's score value.
        ScoreManager.score += scoreValue;

        // After 2 seconds destory the enemy.
        Destroy (gameObject, 2f);
    }
}
}

我把日志放在各处,发现 PlayerShooting 脚本中的 enemyHealth 对象总是返回 Null,即使我用子弹击中敌人也是如此。

PlayerShooting script Screenshot

Unity Screenshot

需要知道为什么它总是返回 Null 以及我如何在击中敌人时返回 Null 以外的值。

最佳答案

您已经在使用 Layer 来确保光线转换仅命中 shootableMask 层上的游戏对象,该层是“Shootable”层,因此消除了层问题。

剩下的唯一可能的问题是 EnemyHealth脚本未附加到游戏对象或某些游戏对象。

遍历所有游戏对象和预制件,在“可射击”层上选择每一个,然后确保 EnemyHealth脚本附在他们身上GetComponent <EnemyHealth>()永远不应该是 null如果EnemyHealth每一个都附有脚本。

关于c# - Unity Survival Shooter Enemy 不受伤害 - Android,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45896484/

相关文章:

c# - 如何验证 .NET 自包含的单个文件可执行文件?

java - Android Asynctask : Use weak reference for context to avoid device rotate screen

java - android:elevation 不适用于 BottomNavigationView

c# - 试图让程序等待几秒钟,然后使用 Unity 在 C# 中继续

android - 如何在Unity 5.3.5中实现Google AdMob中介

c# - DeflateStream/GZipStream 到 CryptoStream,反之亦然

c# - 将 Viewbag 元素 (int) 传递到列表集合索引中

c# - 如何获取具有指定名称的 DataMemberAttribute 的属性?

android - 更改 Android imageButton 在旧图像后面绘制新图像

c# - 如何统一使用.Net 4.6.1?