first commit
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace YueDestructibles
|
||||
{
|
||||
[RequireComponent(typeof(Rigidbody))]
|
||||
public class YueDestructible : MonoBehaviour
|
||||
{
|
||||
[Header("Destruction Properties")]
|
||||
public float shatterBounceMultiplier = 3f;
|
||||
public float maximumImpulse = 1.5f;
|
||||
public float impulseDamageMultiplier = 30f;
|
||||
public bool accumulateDamage = false;
|
||||
|
||||
[Header("Health [%]")]
|
||||
[SerializeField]
|
||||
[Range(0f, 100f)]
|
||||
private float health = 100f;
|
||||
|
||||
[Header("Debris Disappearance")]
|
||||
public bool isDisappearing = true;
|
||||
public float disappearingTime = 5f;
|
||||
|
||||
[Header("Sound Effects")]
|
||||
public AudioClip[] destructionClips;
|
||||
public float impulseVolumeFactor = 0.5f;
|
||||
public YueDestructableAudioSourceTemplate audioSourceTemplate;
|
||||
|
||||
[Header("Dependencies")]
|
||||
public GameObject debrisRoot;
|
||||
[Header("Events")]
|
||||
public UnityEvent onObjectDestruct;
|
||||
// variables
|
||||
#region
|
||||
private Renderer mainObjectRenderer;
|
||||
private Rigidbody[] debris;
|
||||
private Rigidbody rigid;
|
||||
|
||||
private bool isDestructed = false;
|
||||
private bool isSetup = false;
|
||||
#endregion
|
||||
|
||||
private void Start()
|
||||
{
|
||||
// disable deris meshes
|
||||
debrisRoot.SetActive(false);
|
||||
// get list of debris rigidbodies
|
||||
debris = debrisRoot.GetComponentsInChildren<Rigidbody>();
|
||||
// get renderer to determine object size
|
||||
mainObjectRenderer = GetComponent<Renderer>();
|
||||
// get main rigidbody
|
||||
rigid = GetComponent<Rigidbody>();
|
||||
// check UnityEvent
|
||||
if (onObjectDestruct == null)
|
||||
onObjectDestruct = new UnityEvent();
|
||||
|
||||
isSetup = true;
|
||||
}
|
||||
private void OnCollisionEnter(Collision collision)
|
||||
{
|
||||
if (!isSetup)
|
||||
return;
|
||||
|
||||
if (collision.impulse.magnitude > maximumImpulse)
|
||||
{
|
||||
DestructWithImpulse(collision.impulse, collision.GetContact(0).point);
|
||||
}
|
||||
|
||||
if (!accumulateDamage)
|
||||
return;
|
||||
|
||||
health -= collision.impulse.magnitude * impulseDamageMultiplier;
|
||||
|
||||
if (health < 0f)
|
||||
DestructWithImpulse(collision.impulse, collision.GetContact(0).point);
|
||||
}
|
||||
|
||||
public void DestructWithImpulse(Vector3 impulse, Vector3 point)
|
||||
{
|
||||
if (isDestructed)
|
||||
return;
|
||||
|
||||
if (debris.Length <= 0)
|
||||
return;
|
||||
|
||||
// active and unparent root
|
||||
debrisRoot.SetActive(true);
|
||||
debrisRoot.transform.parent = null;
|
||||
|
||||
// inherit main rigid velocity
|
||||
foreach (Rigidbody rb in debris)
|
||||
{
|
||||
if (!rb)
|
||||
break;
|
||||
|
||||
// set active
|
||||
rb.gameObject.SetActive(true);
|
||||
|
||||
// apply propertie
|
||||
rb.mass = rigid.mass / debris.Length;
|
||||
rb.drag = rigid.drag;
|
||||
rb.angularDrag = rigid.angularDrag;
|
||||
|
||||
// add velocity
|
||||
rb.velocity = rigid.velocity;
|
||||
rb.angularVelocity = rigid.angularVelocity;
|
||||
|
||||
// add impulse
|
||||
rb.AddExplosionForce(impulse.magnitude * shatterBounceMultiplier, point, mainObjectRenderer.bounds.max.magnitude);
|
||||
}
|
||||
|
||||
// create sound effect
|
||||
CreateAudioEffect(impulse, point);
|
||||
|
||||
// set flag
|
||||
isDestructed = true;
|
||||
|
||||
// setup root, if disappearing
|
||||
if (isDisappearing)
|
||||
{
|
||||
debrisRoot.AddComponent<YueDestructiblesRoot>();
|
||||
debrisRoot.GetComponent<YueDestructiblesRoot>().SetDebris(debris);
|
||||
debrisRoot.GetComponent<YueDestructiblesRoot>().SetDisappearingTime(disappearingTime);
|
||||
}
|
||||
|
||||
// invoke event
|
||||
onObjectDestruct.Invoke();
|
||||
|
||||
// destroy intact object
|
||||
Destroy(this.gameObject);
|
||||
}
|
||||
public void DestructSimple()
|
||||
{
|
||||
DestructWithImpulse(Vector3.zero, transform.position);
|
||||
}
|
||||
public void AddDamage(float damageInPercent)
|
||||
{
|
||||
health -= damageInPercent;
|
||||
}
|
||||
|
||||
private void CreateAudioEffect(Vector3 impulse, Vector3 point)
|
||||
{
|
||||
if (destructionClips.Length <= 0)
|
||||
return;
|
||||
|
||||
// instatiate sound effect
|
||||
GameObject effect = Instantiate<GameObject>(audioSourceTemplate.gameObject, point, Quaternion.identity);
|
||||
|
||||
// init debris
|
||||
YueDestructableAudioSourceTemplate templateClone = effect.GetComponent<YueDestructableAudioSourceTemplate>();
|
||||
templateClone.debris = debrisRoot.GetComponentsInChildren<Transform>();
|
||||
|
||||
templateClone.audioSource.volume = impulseVolumeFactor * impulse.magnitude;
|
||||
|
||||
// play random sound
|
||||
templateClone.audioSource.PlayOneShot(destructionClips[Random.Range(0, destructionClips.Length)]);
|
||||
Destroy(effect, 5f);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user