using UnityEngine; using System.Collections; using System.Collections.Generic; using GameKitController.Audio; using UnityEngine.Events; public class destroyableObject : MonoBehaviour { [Header ("Main Settings")] [Space] public bool explosionEnabled = true; public GameObject destroyedParticles; public AudioClip destroyedSound; public AudioElement destroyedAudioElement; [Space] [Header ("Explosion Settings")] [Space] public bool useExplosionForceWhenDestroyed; public float explosionRadius; public float explosionForce; public float explosionDamage; public bool ignoreShield; public int damageTypeID = -1; public bool damageCanBeBlocked = true; public bool killObjectsInRadius; public ForceMode forceMode; public bool applyExplosionForceToVehicles = true; public float explosionForceToVehiclesMultiplier = 0.2f; public bool pushCharactersOnExplosion = true; public bool searchClosestWeakSpot; [Space] [Header ("Damage Over Time Settings")] [Space] public bool damageTargetOverTime; public float damageOverTimeDelay; public float damageOverTimeDuration; public float damageOverTimeAmount; public float damageOverTimeRate; public bool damageOverTimeToDeath; public bool removeDamageOverTimeState; [Space] [Header ("Detect Objects Settings")] [Space] public bool userLayerMask; public LayerMask layer; [Space] [Header ("Remote Events Settings")] [Space] public bool useRemoteEventOnObjectsFound; public string removeEventName; [Space] [Header ("Object Pieces Settings")] [Space] public bool fadePiecesEnabled = true; public float timeToFadePieces; public bool storeRendererParts = true; public bool disableColliders = true; public bool destroyObjectAfterFacePieces = true; public Shader transparentShader; public string defaultShaderName = "Legacy Shaders/Transparent/Diffuse"; [Space] [Header ("Meshes Force Settings")] [Space] public float meshesExplosionForce = 500; public float meshesExplosionRadius = 50; public ForceMode meshesExplosionForceMode; [Space] [Header ("Extra Pieces Settings")] [Space] public bool useExtraParts; public List extraParts = new List (); [Space] [Header ("Events Settings")] [Space] public bool useEventOnObjectDestroyed; public UnityEvent eventOnObjectDestroyed; public bool useEventOnObjectBeforeDestroyed; public UnityEvent eventOnObjectBeforeDestroyed; [Space] [Header ("Debug")] [Space] public bool destroyed; [Space] [Header ("Gizmo Settings")] [Space] public bool showGizmo; [Space] [Header ("Components")] [Space] public Rigidbody mainRigidbody; public mapObjectInformation mapInformationManager; public AudioSource destroyedSource; public Transform explosionCenter; List rendererParts = new List (); bool objectDisabled; void Start () { if (mainRigidbody == null) { mainRigidbody = GetComponent (); } if (mapInformationManager == null) { mapInformationManager = GetComponent (); } if (destroyedSource == null) { destroyedSource = GetComponent (); } if (destroyedSound != null) { destroyedAudioElement.clip = destroyedSound; } if (destroyedSource != null) { destroyedAudioElement.audioSource = destroyedSource; } } void Update () { if (destroyed && !objectDisabled) { if (destroyObjectAfterFacePieces) { if (timeToFadePieces > 0) { timeToFadePieces -= Time.deltaTime; } if (storeRendererParts) { if (timeToFadePieces <= 0) { if (fadePiecesEnabled) { int piecesAmountFade = 0; for (int i = 0; i < rendererParts.Count; i++) { Color alpha = rendererParts [i].color; alpha.a -= Time.deltaTime / 5; rendererParts [i].color = alpha; if (alpha.a <= 0) { piecesAmountFade++; } } if (piecesAmountFade == rendererParts.Count) { Destroy (gameObject); } } else { Destroy (gameObject); } } } else { if (timeToFadePieces <= 0) { Destroy (gameObject); } } } else { objectDisabled = true; } } } //Destroy the object public void destroyObject () { if (!explosionEnabled) { return; } if (destroyed) { return; } //instantiated an explosiotn particles if (destroyedParticles != null) { GameObject destroyedParticlesClone = (GameObject)Instantiate (destroyedParticles, transform.position, transform.rotation); destroyedParticlesClone.transform.SetParent (transform); } if (destroyedAudioElement != null) { AudioPlayer.PlayOneShot (destroyedAudioElement, gameObject); } //set the velocity of the object to zero if (mainRigidbody != null) { mainRigidbody.linearVelocity = Vector3.zero; mainRigidbody.isKinematic = true; } //get every renderer component if the object if (storeRendererParts) { if (fadePiecesEnabled) { if (transparentShader == null) { transparentShader = Shader.Find (defaultShaderName); } } Component[] components = GetComponentsInChildren (typeof(MeshRenderer)); List componentsList = new List (components); if (useExtraParts) { int extraPartsCount = extraParts.Count; for (int j = 0; j < extraPartsCount; j++) { GameObject currentObject = extraParts [j]; if (currentObject != null) { Component[] extraComponents = currentObject.GetComponentsInChildren (typeof(MeshRenderer)); if (extraComponents.Length > 0) { componentsList.AddRange (extraComponents); } } } } int ignoreRaycastLayerIndex = LayerMask.NameToLayer ("Ignore Raycast"); int layerToIgnoreIndex = LayerMask.NameToLayer ("Scanner"); int componentsListCount = componentsList.Count; for (int i = 0; i < componentsListCount; i++) { MeshRenderer child = componentsList [i] as MeshRenderer; if (child != null && child.gameObject.layer != layerToIgnoreIndex) { if (child.enabled) { if (fadePiecesEnabled) { //for every renderer object, change every shader in it for a transparent shader for (int j = 0; j < child.materials.Length; j++) { child.materials [j].shader = transparentShader; rendererParts.Add (child.materials [j]); } } //set the layer ignore raycast to them child.gameObject.layer = ignoreRaycastLayerIndex; //add rigidbody and box collider to them Rigidbody currentRigidbody = child.gameObject.GetComponent (); if (currentRigidbody == null) { currentRigidbody = child.gameObject.AddComponent (); } else { currentRigidbody.isKinematic = false; currentRigidbody.useGravity = true; } Collider currentCollider = child.gameObject.GetComponent (); if (currentCollider == null) { currentCollider = child.gameObject.AddComponent (); } //apply explosion force currentRigidbody.AddExplosionForce (meshesExplosionForce, transform.position, meshesExplosionRadius, 3, meshesExplosionForceMode); } } } } if (disableColliders) { //any other object with a collider but with out renderer, is disabled Component[] collidersInObject = GetComponentsInChildren (typeof(Collider)); int collidersInObjectLength = collidersInObject.Length; for (int i = 0; i < collidersInObjectLength; i++) { Collider currentCollider = collidersInObject [i] as Collider; if (currentCollider != null && !currentCollider.GetComponent ()) { currentCollider.enabled = false; } } } if (mapInformationManager != null) { mapInformationManager.removeMapObject (); } if (useEventOnObjectBeforeDestroyed) { eventOnObjectBeforeDestroyed.Invoke (); } if (useExplosionForceWhenDestroyed) { if (explosionCenter == null) { explosionCenter = transform; } Vector3 currentPosition = explosionCenter.position; applyDamage.setExplosion (currentPosition, explosionRadius, userLayerMask, layer, gameObject, false, gameObject, killObjectsInRadius, true, false, explosionDamage, pushCharactersOnExplosion, applyExplosionForceToVehicles, explosionForceToVehiclesMultiplier, explosionForce, forceMode, true, transform, ignoreShield, useRemoteEventOnObjectsFound, removeEventName, damageTypeID, damageTargetOverTime, damageOverTimeDelay, damageOverTimeDuration, damageOverTimeAmount, damageOverTimeRate, damageOverTimeToDeath, removeDamageOverTimeState, damageCanBeBlocked, searchClosestWeakSpot); } if (useEventOnObjectDestroyed) { eventOnObjectDestroyed.Invoke (); } destroyed = true; } #if UNITY_EDITOR void OnDrawGizmos () { if (!showGizmo) { return; } if (GKC_Utils.isCurrentSelectionActiveGameObject (gameObject)) { DrawGizmos (); } } void OnDrawGizmosSelected () { DrawGizmos (); } void DrawGizmos () { if (showGizmo) { if (useExplosionForceWhenDestroyed) { Gizmos.color = Color.red; Gizmos.DrawWireSphere (transform.position, explosionRadius); } } } #endif }