Unity3D經典案例遊戲:TANKS! Unity Tutorial - Phase 4 of 8 - Tank Health——ShellExplosion相關源C#代碼解析

該源代碼轉載自Unity遊戲案例中的TANKS代碼中

------------來自第二次使用Unity3D製作遊戲的遊戲製作新人小白

一、代碼自我解析

二、油管學習地址

三、Unity3D源代碼

 

 

一、源代碼自我解析

using UnityEngine;

public class ShellExplosion : MonoBehaviour
{
    public LayerMask m_TankMask;                        // 加載玩家
    public ParticleSystem m_ExplosionParticles;         // 加載粒子效果(炮彈爆炸)
    public AudioSource m_ExplosionAudio;                // 加載爆炸音效
    public float m_MaxDamage = 100f;                    // 設置最大傷害數值
    public float m_ExplosionForce = 1000f;              // 加載爆炸中心的坦克的力
    public float m_MaxLifeTime = 2f;                    // 移除炮彈前的時間,以秒爲單位
    public float m_ExplosionRadius = 5f;                // 爆炸半徑


    private void Start()
    {
        // 如果到那時它還沒有被銷燬,那就在它的生命週期結束後銷燬它。
        Destroy(gameObject, m_MaxLifeTime);
    }


    private void OnTriggerEnter(Collider other)
    {
        // Find all the tanks in an area around the shell and damage them.
        Collider[] colliders = Physics.OverlapSphere(transform.position, m_ExplosionRadius, m_TankMask);

        // 遍歷所有碰撞器
        for (int i = 0; i < colliders.Length; i++)
        {
            // 並尋找其他剛體
            Rigidbody targetRigidbody = colliders[i].GetComponent<Rigidbody>();

            // 如果沒有找到剛體,就繼續循環尋找碰撞器
            if (!targetRigidbody)
                continue;

            // 施加一個爆炸力
            targetRigidbody.AddExplosionForce(m_ExplosionForce, transform.position, m_ExplosionRadius);

            // 找到與坦克生命值代碼關聯的剛體
            TankHealth targetHealth = targetRigidbody.GetComponent<TankHealth>();

            // 如果沒找到關聯有坦克生命值代碼的剛體,就繼續下一個碰撞檢測
            if (!targetHealth)
                continue;

            // 計算炮彈傷害
            float damage = CalculateDamage(targetRigidbody.position);

            //對坦克的生命值進行重計算(結算傷害)
            targetHealth.TakeDamage(damage);
        }

        // 將爆炸的父對象設爲空
        m_ExplosionParticles.transform.parent = null;

        // 播放爆炸粒子特效
        m_ExplosionParticles.Play();

        // 播放爆炸粒子音效
        m_ExplosionAudio.Play();

        // 一旦粒子完成,摧毀他們的遊戲對象
        ParticleSystem.MainModule mainModule = m_ExplosionParticles.main;
        Destroy(m_ExplosionParticles.gameObject, mainModule.duration);

        Destroy(gameObject);
    }


    private float CalculateDamage(Vector3 targetPosition)
    {
        // Calculate the amount of damage a target should take based on it's position.

        // 創建一個從炮彈到目標的向量
        Vector3 explosionToTarget = targetPosition - transform.position;

        // 計算炮彈到目標的距離
        float explosionDistance = explosionToTarget.magnitude;

        // 計算目標離開的最大距離(爆炸半徑)的比例
        float relativeDistance = (m_ExplosionRadius - explosionDistance) / m_ExplosionRadius;

        // 根據最大可能傷害的比例計算傷害值。
        float damage = relativeDistance * m_MaxDamage;

        //確保最小傷害值總是爲0
        damage = Mathf.Max(0f, damage);

        return damage;
    }
}

// 以上只是自己對於該代碼的理解,如有誤還望指出讓我及時改正。

 

二、油管學習Unity地址  

 

https://www.youtube.com/watch?v=paLLfWd2k5A

 

三、Unity3D中該案例源代碼:

using UnityEngine;

namespace Complete
{
    public class ShellExplosion : MonoBehaviour
    {
        public LayerMask m_TankMask;                        // Used to filter what the explosion affects, this should be set to "Players".
        public ParticleSystem m_ExplosionParticles;         // Reference to the particles that will play on explosion.
        public AudioSource m_ExplosionAudio;                // Reference to the audio that will play on explosion.
        public float m_MaxDamage = 100f;                    // The amount of damage done if the explosion is centred on a tank.
        public float m_ExplosionForce = 1000f;              // The amount of force added to a tank at the centre of the explosion.
        public float m_MaxLifeTime = 2f;                    // The time in seconds before the shell is removed.
        public float m_ExplosionRadius = 5f;                // The maximum distance away from the explosion tanks can be and are still affected.


        private void Start ()
        {
            // If it isn't destroyed by then, destroy the shell after it's lifetime.
            Destroy (gameObject, m_MaxLifeTime);
        }


        private void OnTriggerEnter (Collider other)
        {
			// Collect all the colliders in a sphere from the shell's current position to a radius of the explosion radius.
            Collider[] colliders = Physics.OverlapSphere (transform.position, m_ExplosionRadius, m_TankMask);

            // Go through all the colliders...
            for (int i = 0; i < colliders.Length; i++)
            {
                // ... and find their rigidbody.
                Rigidbody targetRigidbody = colliders[i].GetComponent<Rigidbody> ();

                // If they don't have a rigidbody, go on to the next collider.
                if (!targetRigidbody)
                    continue;

                // Add an explosion force.
                targetRigidbody.AddExplosionForce (m_ExplosionForce, transform.position, m_ExplosionRadius);

                // Find the TankHealth script associated with the rigidbody.
                TankHealth targetHealth = targetRigidbody.GetComponent<TankHealth> ();

                // If there is no TankHealth script attached to the gameobject, go on to the next collider.
                if (!targetHealth)
                    continue;

                // Calculate the amount of damage the target should take based on it's distance from the shell.
                float damage = CalculateDamage (targetRigidbody.position);

                // Deal this damage to the tank.
                targetHealth.TakeDamage (damage);
            }

            // Unparent the particles from the shell.
            m_ExplosionParticles.transform.parent = null;

            // Play the particle system.
            m_ExplosionParticles.Play();

            // Play the explosion sound effect.
            m_ExplosionAudio.Play();

            // Once the particles have finished, destroy the gameobject they are on.
            ParticleSystem.MainModule mainModule = m_ExplosionParticles.main;
            Destroy (m_ExplosionParticles.gameObject, mainModule.duration);

            // Destroy the shell.
            Destroy (gameObject);
        }


        private float CalculateDamage (Vector3 targetPosition)
        {
            // Create a vector from the shell to the target.
            Vector3 explosionToTarget = targetPosition - transform.position;

            // Calculate the distance from the shell to the target.
            float explosionDistance = explosionToTarget.magnitude;

            // Calculate the proportion of the maximum distance (the explosionRadius) the target is away.
            float relativeDistance = (m_ExplosionRadius - explosionDistance) / m_ExplosionRadius;

            // Calculate damage as this proportion of the maximum possible damage.
            float damage = relativeDistance * m_MaxDamage;

            // Make sure that the minimum damage is always 0.
            damage = Mathf.Max (0f, damage);

            return damage;
        }
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章