子弹爆炸 是一个范围性的爆炸,整个过程有四部分
1.在该范围内的坦克都会受到冲击力(减血、位移)
2.而且会播放一个爆炸的粒子效果
3.播放音效
4.子弹消失
1UI模型搭建
一个SHELL模型 + ShellExplosion爆炸粒子系统
其中Shell 中 应该有
一个Collider用于触发物理碰撞 -----------胶囊型封装器 Capsule Collider
一个RigidBody使其具有物理属性,比如受力
当然还有一个ShellExplosion粒子系统
及相应控制爆炸过程的 script
思考一下 ShellExplosion 爆炸的时候需要什么
1.物理特效 --------- PaticalSystem ExplosionParticles
2.音效 ------------ AudioSource ExplosionAudio
3.爆炸半径 ---------- float ExplosionRadius
4.爆炸时间 ---------- float maxLifeTime
5.爆炸产生的冲击力 ------- float ExplosionForce
6. 爆炸造成的最大伤害 ----- float maxDamage
7.作用对象 --------LayerMask TankMask
再考虑一下 从外部引用还是内部定义获取 ,都是从外部引用 Public
对UI进行相关的设置之后 (Collider的大小和位置, 添加各种组件 )
直接PO代码
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) { // 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. Destroy (m_ExplosionParticles.gameObject, m_ExplosionParticles.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; } }
比较值得注意和学习的
Collider[] colliders = Physics.OverlapSphere (transform.position, m_ExplosionRadius, m_TankMask); //这个函数以某一位置,某一半径,以及相关的LayerMask作为区分 ,获取球形区域内物体的Collider
targetRigidbody.AddExplosionForce (m_ExplosionForce, transform.position, m_ExplosionRadius);//这个函数,则是RigidBody自带的,根据FORCE , POSITION , ExplosionRadius对自身施加爆炸冲击力
// Find the TankHealth script associated with the rigidbody.
TankHealth targetHealth = targetRigidbody.GetComponent<TankHealth> (); //泛型获取一个 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);