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;
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值