Init
This commit is contained in:
9
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors.meta
vendored
Normal file
9
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors.meta
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f3a99b6d396c32a4eb2a3f34dc6a99b0
|
||||
folderAsset: yes
|
||||
timeCreated: 1427397479
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
49
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/ActivateDestructibles.cs
vendored
Normal file
49
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/ActivateDestructibles.cs
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
using UnityEngine;
|
||||
// ReSharper disable IdentifierTypo
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
public class ActivateDestructibles : MonoBehaviour
|
||||
{
|
||||
private DestructionManager _destructionManager;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
_destructionManager = DestructionManager.Instance;
|
||||
if (_destructionManager == null)
|
||||
{
|
||||
Debug.LogError("DestructionManager could not be found or created in the scene. Removing script.");
|
||||
Destroy(this);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnTriggerEnter(Collider other)
|
||||
{
|
||||
// Ignore Player objects
|
||||
if (other.gameObject.CompareTag("Player")) return;
|
||||
|
||||
Destructible destructible = other.gameObject.GetComponentInParent<Destructible>();
|
||||
if (destructible == null) return;
|
||||
|
||||
if (destructible.isTerrainTree && _destructionManager.destructibleTreesStayDeactivated) return;
|
||||
|
||||
if (!destructible.enabled)
|
||||
destructible.enabled = true;
|
||||
}
|
||||
|
||||
private void OnTriggerExit(Collider other)
|
||||
{
|
||||
// Ignore Player objects
|
||||
if (other.gameObject.CompareTag("Player")) return;
|
||||
|
||||
Destructible destructible = other.gameObject.GetComponentInParent<Destructible>();
|
||||
if (destructible == null) return;
|
||||
|
||||
if (destructible.enabled && !destructible.isTerrainTree && _destructionManager.autoDeactivateDestructibles) // deactivate non-terrain trees
|
||||
destructible.shouldDeactivate = true;
|
||||
else if (destructible.enabled && destructible.isTerrainTree && _destructionManager.autoDeactivateDestructibleTerrainObjects) // deactivate terrain trees
|
||||
destructible.shouldDeactivate = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
11
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/ActivateDestructibles.cs.meta
vendored
Normal file
11
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/ActivateDestructibles.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a3678786273380f499d192333f4cc2a0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
46
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/AutoDamage.cs
vendored
Normal file
46
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/AutoDamage.cs
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
public class AutoDamage : MonoBehaviour
|
||||
{
|
||||
public int startAtHitPoints = 30;
|
||||
public float damageIntervalSeconds = 0.5f;
|
||||
public int damagePerInterval = 5;
|
||||
|
||||
private bool _isInitialized;
|
||||
private Destructible _destructible;
|
||||
private bool _autoDamageStarted;
|
||||
|
||||
void Start()
|
||||
{
|
||||
_destructible = gameObject.GetComponent<Destructible>();
|
||||
if (_destructible == null)
|
||||
{
|
||||
Debug.LogWarning("No Destructible object found! AutoDamage removed.");
|
||||
Destroy(this);
|
||||
}
|
||||
_isInitialized = true;
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (!_isInitialized) return;
|
||||
if (_destructible == null) return;
|
||||
if (_autoDamageStarted) return;
|
||||
|
||||
if (_destructible.CurrentHitPoints <= startAtHitPoints)
|
||||
{
|
||||
InvokeRepeating("ApplyDamage", 0f, damageIntervalSeconds);
|
||||
_autoDamageStarted = true;
|
||||
}
|
||||
}
|
||||
|
||||
void ApplyDamage()
|
||||
{
|
||||
if (_destructible == null) return;
|
||||
|
||||
_destructible.ApplyDamage(damagePerInterval);
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/AutoDamage.cs.meta
vendored
Normal file
13
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/AutoDamage.cs.meta
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a497b0926a01c584086140c092748bd6
|
||||
timeCreated: 1526789610
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
126
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/ChainDestruction.cs
vendored
Normal file
126
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/ChainDestruction.cs
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
// ReSharper disable ForCanBeConvertedToForeach
|
||||
// ReSharper disable CommentTypo
|
||||
// ReSharper disable IdentifierTypo
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
[RequireComponent(typeof(Destructible))]
|
||||
[RequireComponent(typeof(Rigidbody))]
|
||||
public class ChainDestruction : MonoBehaviour
|
||||
{
|
||||
[Tooltip("The amount of damage to apply per second to adjacent Destructible objects in the destructible chain. This will control how fast objects are destroyed.")]
|
||||
public float damagePerSecond = 125f;
|
||||
|
||||
[Tooltip("If you would like to apply force on the debris pieces from a specific position point, you can assign a specific Transform location for that here. If you leave this empty, the gameObject's position will be used as the force origin point.")]
|
||||
public Transform forcePosition;
|
||||
|
||||
[Tooltip("The amount of force to apply to the debris pieces (if any) when they are destroyed.")]
|
||||
public float forceAmount = 300f;
|
||||
|
||||
[Tooltip("The size in game units (usually meters) of the force radius. A larger force radius will make debris pieces (if any) fly farther away from the force origin point.")]
|
||||
public float forceRadius = 5f;
|
||||
|
||||
[Tooltip("The amount of upward push exerted on the debris pieces (if any). More upward push can make the force look more interesting or cinematic, but too much (say, over 2) can be unrealistic.")]
|
||||
public float forceUpwardModifier;
|
||||
|
||||
[HideInInspector]
|
||||
public List<Destructible> adjacentDestructibles; // This is a list of adjacent Destructible objects, ones overlapping the trigger collider of this object.
|
||||
|
||||
[Tooltip("Set to TRUE to cause this Destructible object to start taking damage at the predefined damage rate (Damage Per Second).")]
|
||||
public bool destroySelf;
|
||||
|
||||
private Destructible _destObj; // Reference to the Destructible component on this gameObject.
|
||||
|
||||
private void Start()
|
||||
{
|
||||
adjacentDestructibles = new List<Destructible>();
|
||||
|
||||
// Attempt to get the Destructible script on the object. If found, attach the OnDestroyed event listener to the DestroyedEvent.
|
||||
_destObj = gameObject.GetComponent<Destructible>();
|
||||
if (_destObj != null)
|
||||
_destObj.DestroyedEvent += OnDestroyed;
|
||||
|
||||
if (!HasTriggerCollider())
|
||||
Debug.LogWarning("No trigger collider found on ChainDestruction gameObject. You need a trigger collider for this script to work properly.");
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!destroySelf) return;
|
||||
|
||||
if (damagePerSecond > 0f)
|
||||
{
|
||||
// If you don't care about adding force to the debris pieces, uncomment this code to use a simpler method of applying damage.
|
||||
//destObj.ApplyDamage(damagePerSecond * Time.fixedDeltaTime);
|
||||
//return;
|
||||
|
||||
// Apply damage with force on the debris pieces.
|
||||
Damage damage = new ExplosiveDamage()
|
||||
{
|
||||
DamageAmount = damagePerSecond * Time.deltaTime,
|
||||
BlastForce = forceAmount,
|
||||
Position = forcePosition != null ? forcePosition.position : transform.position,
|
||||
Radius = forceRadius,
|
||||
UpwardModifier = forceUpwardModifier
|
||||
};
|
||||
|
||||
_destObj.ApplyDamage(damage);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
// Unregister the event listener when disabled/destroyed. Very important to prevent memory leaks due to orphaned event listeners!
|
||||
if (_destObj == null) return;
|
||||
_destObj.DestroyedEvent -= OnDestroyed;
|
||||
}
|
||||
|
||||
/// <summary>When this Destructible object is destroyed, the code in this method will run.</summary>
|
||||
private void OnDestroyed()
|
||||
{
|
||||
if (adjacentDestructibles == null || adjacentDestructibles.Count == 0) return;
|
||||
|
||||
// For each adjacent Destructible object, set DestroySelf to true for its ChainDestruction component, so it will start taking damage.
|
||||
for (int i = 0; i < adjacentDestructibles.Count; i++)
|
||||
{
|
||||
Destructible adjacentDest = adjacentDestructibles[i];
|
||||
if (adjacentDest == null) continue;
|
||||
ChainDestruction chainDest = adjacentDest.gameObject.GetComponent<ChainDestruction>();
|
||||
if (chainDest == null) continue;
|
||||
chainDest.destroySelf = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnTriggerEnter(Collider other)
|
||||
{
|
||||
// Add the nearby item to the list of adjacent Destructibles.
|
||||
var otherDestObj = other.gameObject.GetComponentInParent<Destructible>();
|
||||
if (otherDestObj != null && !adjacentDestructibles.Contains(otherDestObj))
|
||||
adjacentDestructibles.Add(otherDestObj);
|
||||
}
|
||||
|
||||
private void OnTriggerExit(Collider other)
|
||||
{
|
||||
// Remove the item that is no longer nearby from the list of adjacent Destructibles.
|
||||
var otherDestObj = other.gameObject.GetComponentInParent<Destructible>();
|
||||
if (otherDestObj != null && adjacentDestructibles.Contains(otherDestObj))
|
||||
adjacentDestructibles.Remove(otherDestObj);
|
||||
}
|
||||
|
||||
/// <summary>Returns True if there is a trigger collider on this game object. Otherwise, returns False.</summary>
|
||||
private bool HasTriggerCollider()
|
||||
{
|
||||
Collider[] colls = gameObject.GetComponents<Collider>();
|
||||
if (colls == null) return false;
|
||||
for (int i = 0; i < colls.Length; i++)
|
||||
{
|
||||
if (colls[i].isTrigger)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/ChainDestruction.cs.meta
vendored
Normal file
3
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/ChainDestruction.cs.meta
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: df192195518b4f4f97306fa8b5758eb9
|
||||
timeCreated: 1548308591
|
||||
52
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/ChainDestructionTrigger.cs
vendored
Normal file
52
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/ChainDestructionTrigger.cs
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
using UnityEngine;
|
||||
// ReSharper disable ForCanBeConvertedToForeach
|
||||
// ReSharper disable IdentifierTypo
|
||||
// ReSharper disable LoopCanBeConvertedToQuery
|
||||
// ReSharper disable CommentTypo
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
/// <summary>
|
||||
/// This script triggers a chain destruction sequence on one or more Destructible objects that also have the
|
||||
/// ChainDestruction component. Put this script on a trigger collider and assign one or more Destructible
|
||||
/// objects that have the ChainDestruction component to the ChainDestructions collection.
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(Collider))]
|
||||
public class ChainDestructionTrigger : MonoBehaviour
|
||||
{
|
||||
public ChainDestruction[] chainDestructions;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
if (!HasTriggerCollider())
|
||||
Debug.LogWarning("No trigger collider found on ChainDestructionTrigger gameObject. You need a trigger collider for this script to work properly.");
|
||||
}
|
||||
|
||||
private void OnTriggerEnter(Collider other)
|
||||
{
|
||||
if (chainDestructions == null || chainDestructions.Length == 0) return;
|
||||
|
||||
// For each ChainDestruction component to trigger, set its destroySelf flag to True.
|
||||
for (int i = 0; i < chainDestructions.Length; i++)
|
||||
{
|
||||
if (chainDestructions[i] == null) continue;
|
||||
|
||||
chainDestructions[i].destroySelf = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Returns True if there is a trigger collider on this game object. Otherwise, returns False.</summary>
|
||||
private bool HasTriggerCollider()
|
||||
{
|
||||
Collider[] colls = gameObject.GetComponents<Collider>();
|
||||
if (colls == null) return false;
|
||||
for (int i = 0; i < colls.Length; i++)
|
||||
{
|
||||
if (colls[i].isTrigger)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/ChainDestructionTrigger.cs.meta
vendored
Normal file
11
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/ChainDestructionTrigger.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 383dc81c4944a0e44949828cbc7d186c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
77
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/ChipAwayDebris.cs
vendored
Normal file
77
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/ChipAwayDebris.cs
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
using UnityEngine;
|
||||
// ReSharper disable CommentTypo
|
||||
// ReSharper disable IdentifierTypo
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
/// <summary>
|
||||
/// This script is attached to a debris piece at runtime. Your projectiles should check for collisions with
|
||||
/// ChipAwayDebris and fire the BreakOff() method when impact occurs.
|
||||
/// </summary>
|
||||
public class ChipAwayDebris : MonoBehaviour
|
||||
{
|
||||
public float debrisMass = 1f;
|
||||
public float debrisDrag = 0f;
|
||||
public float debrisAngularDrag = 0.05f;
|
||||
private Renderer _rend;
|
||||
|
||||
public void BreakOff(Vector3 force, Vector3 point)
|
||||
{
|
||||
if (!CheckCanBreakOff()) return;
|
||||
|
||||
// Check whether a rigidbody already exists
|
||||
Rigidbody existingRBody = _rend.gameObject.GetComponent<Rigidbody>();
|
||||
Rigidbody rbody;
|
||||
|
||||
// Make the debris fall away by attaching a rigidbody to it.
|
||||
rbody = existingRBody == null ? _rend.gameObject.AddComponent<Rigidbody>() : existingRBody;
|
||||
rbody.mass = debrisMass;
|
||||
rbody.drag = debrisDrag;
|
||||
rbody.angularDrag = debrisAngularDrag;
|
||||
rbody.AddForceAtPosition(force, point, ForceMode.Impulse);
|
||||
rbody.gameObject.transform.SetParent(null);
|
||||
|
||||
Destroy(this);
|
||||
}
|
||||
|
||||
public void BreakOff(float blastForce, float explosionRadius, float upwardsModifier)
|
||||
{
|
||||
if (!CheckCanBreakOff()) return;
|
||||
|
||||
//Debug.Log("Breaking off");
|
||||
// Make the debris fall away by attaching a rigidbody to it.
|
||||
Rigidbody rbody = _rend.gameObject.AddComponent<Rigidbody>();
|
||||
rbody.mass = debrisMass;
|
||||
rbody.drag = debrisDrag;
|
||||
rbody.angularDrag = debrisAngularDrag;
|
||||
rbody.AddExplosionForce(blastForce, transform.position, explosionRadius, upwardsModifier);
|
||||
|
||||
Destroy(this);
|
||||
}
|
||||
|
||||
private bool CheckCanBreakOff()
|
||||
{
|
||||
// If no collider is on this object, then something weird happened. Exit and destroy self.
|
||||
if (GetComponent<Collider>() == null)
|
||||
{
|
||||
Destroy(this);
|
||||
return false;
|
||||
}
|
||||
|
||||
_rend = gameObject.GetComponentInParent<Renderer>();
|
||||
if (_rend == null)
|
||||
{
|
||||
Destroy(this);
|
||||
return false;
|
||||
}
|
||||
|
||||
// If a rigidbody already exists on this debris piece, remove this script and exit.
|
||||
if (GetComponent<Collider>().attachedRigidbody != null)
|
||||
{
|
||||
Destroy(this);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/ChipAwayDebris.cs.meta
vendored
Normal file
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/ChipAwayDebris.cs.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 21475ccb6d09a1e4bbd5cd92987edc19
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
16
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/ClingPoint.cs
vendored
Normal file
16
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/ClingPoint.cs
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
public class ClingPoint : MonoBehaviour
|
||||
{
|
||||
public int chanceToCling = 75;
|
||||
|
||||
private void OnDrawGizmos()
|
||||
{
|
||||
Gizmos.color = Color.yellow;
|
||||
Gizmos.DrawWireSphere(this.transform.position - (this.transform.forward * 0.025f), .01f);
|
||||
Gizmos.DrawRay(this.transform.position - (this.transform.forward * 0.025f), this.transform.forward * 0.075f);
|
||||
}
|
||||
}
|
||||
}
|
||||
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/ClingPoint.cs.meta
vendored
Normal file
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/ClingPoint.cs.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3f5b9e5a44e24a04c85b856c6bdec6d1
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
45
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/DelayedRigidbody.cs
vendored
Normal file
45
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/DelayedRigidbody.cs
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
/// <summary>
|
||||
/// This script is used to add a Rigidbody component to a gameobject through code. It allows you to start with an object that has no Rigidbody
|
||||
/// and add one at a later time by calling Initialize() on this script. The script deletes itself after adding the Rigidbody.
|
||||
/// </summary>
|
||||
public class DelayedRigidbody : MonoBehaviour
|
||||
{
|
||||
public float mass = 1f;
|
||||
public float drag = 0f;
|
||||
public float angularDrag = 0.05f;
|
||||
public float delaySeconds = 0f;
|
||||
public bool reenableColliders = true;
|
||||
|
||||
/// <summary>This is called whenever you want to add a rigidbody to the game object.</summary>
|
||||
public void Initialize()
|
||||
{
|
||||
Invoke("AddRigidbody", delaySeconds);
|
||||
}
|
||||
|
||||
public void AddRigidbody()
|
||||
{
|
||||
// Add a rigidbody component if it doesn't already exist.
|
||||
if (gameObject.GetComponent<Rigidbody>() == null)
|
||||
{
|
||||
Rigidbody rbody = gameObject.AddComponent<Rigidbody>();
|
||||
rbody.mass = mass;
|
||||
rbody.drag = drag;
|
||||
rbody.angularDrag = angularDrag;
|
||||
}
|
||||
|
||||
if (reenableColliders)
|
||||
{
|
||||
Collider[] colliders = gameObject.GetComponentsInChildren<Collider>();
|
||||
foreach(Collider coll in colliders)
|
||||
coll.enabled = true;
|
||||
}
|
||||
|
||||
// Deletes this script when finished.
|
||||
Destroy(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/DelayedRigidbody.cs.meta
vendored
Normal file
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/DelayedRigidbody.cs.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a2817944056bc0b47a421eadf80faab3
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
32
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/DestroyAfter.cs
vendored
Normal file
32
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/DestroyAfter.cs
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
/// <summary>This script will destroy the gameobject it is attached to after [seconds].</summary>
|
||||
public class DestroyAfter : MonoBehaviour
|
||||
{
|
||||
public float seconds; // seconds to wait before destroying this game object.
|
||||
private float timeLeft;
|
||||
private bool isInitialized;
|
||||
|
||||
void Start()
|
||||
{
|
||||
timeLeft = seconds;
|
||||
isInitialized = true;
|
||||
}
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
timeLeft = seconds;
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (!isInitialized) return;
|
||||
|
||||
timeLeft -= Time.deltaTime;
|
||||
if (timeLeft <= 0)
|
||||
Destroy(this.gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/DestroyAfter.cs.meta
vendored
Normal file
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/DestroyAfter.cs.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: de08e9a9bd37ed844b649cf29d176a6c
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
70
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/DestroyOnKeypress.cs
vendored
Normal file
70
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/DestroyOnKeypress.cs
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
/// <summary>
|
||||
/// Put this script on a game object in your scene, and it will destroy Destructible object when you press the associated key.
|
||||
/// </summary>
|
||||
public class DestroyOnKeypress : MonoBehaviour
|
||||
{
|
||||
public float force = 500f;
|
||||
public float radius = 10f;
|
||||
public float upwardModifier = -1;
|
||||
public ObjectToDestroy[] objectsToDestroy;
|
||||
|
||||
void Update()
|
||||
{
|
||||
// Look for keys that may have been pressed.
|
||||
for (int i = 0; i < objectsToDestroy.Length; i++)
|
||||
{
|
||||
if (string.IsNullOrEmpty(objectsToDestroy[i].key)) continue;
|
||||
|
||||
// Get the keycode for each keypress we want to look for
|
||||
KeyCode key = (KeyCode)Enum.Parse(typeof(KeyCode), objectsToDestroy[i].key.ToUpper());
|
||||
|
||||
// If the keypress matches the keycode configured, try to destroy the destructible objects assigned to it
|
||||
if (Input.GetKeyUp(key))
|
||||
{
|
||||
// For each destructible object assigned to this keycode...
|
||||
Destructible[] destObjs = objectsToDestroy[i].destructibles;
|
||||
for (int j = 0; j < destObjs.Length; j++)
|
||||
{
|
||||
if (destObjs[j] == null) continue;
|
||||
|
||||
// If there is a collider on the destructible object, capture the tallest point on the collider. We'll use it to apply force so the object won't be stationary once destroyed.
|
||||
Collider coll = destObjs[j].GetComponentInChildren<Collider>();
|
||||
if (coll != null)
|
||||
{
|
||||
Vector3 pos = destObjs[j].transform.position;
|
||||
Vector3 tallestPoint = coll.ClosestPoint(new Vector3(pos.x, pos.y+5000f, pos.z));
|
||||
|
||||
// Apply the force to a random offset spot around the tallest point of the collider. This will make it so the force is a little unpredictable.
|
||||
float randomX = Random.Range(1, 4);
|
||||
if (Random.Range(0, 2) == 1) randomX *= -1;
|
||||
float randomZ = Random.Range(1, 4);
|
||||
if (Random.Range(0, 2) == 1) randomZ *= -1;
|
||||
Vector3 forcePoint = new Vector3(tallestPoint.x + randomX, tallestPoint.y, tallestPoint.z + randomZ);
|
||||
|
||||
// Apply the damage, with random force added
|
||||
destObjs[j].ApplyDamage(new ExplosiveDamage {
|
||||
BlastForce = force, DamageAmount = destObjs[j].CurrentHitPoints + 1,
|
||||
Position = forcePoint, Radius = radius, UpwardModifier = upwardModifier
|
||||
});
|
||||
}
|
||||
else // If there is no collider on the Destructible object, just destroy it
|
||||
destObjs[j].Destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class ObjectToDestroy
|
||||
{
|
||||
public string key;
|
||||
public Destructible[] destructibles;
|
||||
}
|
||||
}
|
||||
11
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/DestroyOnKeypress.cs.meta
vendored
Normal file
11
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/DestroyOnKeypress.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fe486b865324dee46aed1f765abb5950
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
483
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/Destructible.cs
vendored
Normal file
483
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/Destructible.cs
vendored
Normal file
@@ -0,0 +1,483 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
// ReSharper disable ArrangeAccessorOwnerBody
|
||||
// ReSharper disable UnusedMember.Global
|
||||
// ReSharper disable ForCanBeConvertedToForeach
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
/// <summary>Put this script on an object you want to be destructible.</summary>
|
||||
[DisallowMultipleComponent]
|
||||
public class Destructible : MonoBehaviour
|
||||
{
|
||||
public float TotalHitPoints
|
||||
{
|
||||
get { return _totalHitPoints; }
|
||||
set
|
||||
{
|
||||
_totalHitPoints = value;
|
||||
damageLevels.CalculateDamageLevels(_totalHitPoints);
|
||||
}
|
||||
}
|
||||
|
||||
public float CurrentHitPoints
|
||||
{
|
||||
get { return _currentHitPoints; }
|
||||
set { _currentHitPoints = value; }
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
[FormerlySerializedAs("totalHitPoints")]
|
||||
[HideInInspector]
|
||||
private float _totalHitPoints = 50f;
|
||||
|
||||
[SerializeField]
|
||||
[FormerlySerializedAs("currentHitPoints")]
|
||||
[HideInInspector]
|
||||
private float _currentHitPoints = 50f;
|
||||
|
||||
[HideInInspector] public List<DamageLevel> damageLevels;
|
||||
[HideInInspector] public GameObject destroyedPrefab;
|
||||
[HideInInspector] public GameObject destroyedPrefabParent;
|
||||
[HideInInspector] public ParticleSystem fallbackParticle;
|
||||
[HideInInspector] public int fallbackParticleMatOption;
|
||||
[HideInInspector] public List<DamageEffect> damageEffects;
|
||||
[HideInInspector] public float velocityReduction = .5f;
|
||||
[HideInInspector] public bool limitDamage = false;
|
||||
[HideInInspector] public float minDamage = 10f; // The minimum amount of damage the object can receive per hit.
|
||||
[HideInInspector] public float maxDamage = 100f; // The maximum amount of damage the object can receive per hit.
|
||||
[HideInInspector] public float minDamageTime = 0f; // The minimum amount of time (in seconds) that must pass before the object can be damaged again.
|
||||
[HideInInspector] public float ignoreCollisionsUnder = 2f;
|
||||
[HideInInspector] public List<GameObject> unparentOnDestroy;
|
||||
[HideInInspector] public bool disableKinematicOnUparentedChildren = true;
|
||||
[HideInInspector] public List<MaterialMapping> replaceMaterials;
|
||||
[HideInInspector] public List<MaterialMapping> replaceParticleMats;
|
||||
[HideInInspector] public bool canBeDestroyed = true;
|
||||
[HideInInspector] public bool canBeRepaired = true;
|
||||
[HideInInspector] public List<string> debrisToReParentByName;
|
||||
[HideInInspector] public bool debrisToReParentIsKinematic;
|
||||
[HideInInspector] public List<string> childrenToReParentByName;
|
||||
[HideInInspector] public bool isDebrisChipAway;
|
||||
[HideInInspector] public float chipAwayDebrisMass = 1f;
|
||||
[HideInInspector] public float chipAwayDebrisDrag;
|
||||
[HideInInspector] public float chipAwayDebrisAngularDrag = 0.05f;
|
||||
[HideInInspector] public bool autoPoolDestroyedPrefab = true;
|
||||
[HideInInspector] public bool useFallbackParticle = true;
|
||||
[HideInInspector] public Vector3 centerPointOverride;
|
||||
[HideInInspector] public Vector3 fallbackParticleScale = Vector3.one;
|
||||
[HideInInspector] public Transform fallbackParticleParent;
|
||||
[HideInInspector] public bool sinkWhenDestroyed;
|
||||
[HideInInspector] public bool shouldDeactivate; // If true, this script will deactivate after a set period of time (configurable on DestructionManager).
|
||||
[HideInInspector] public bool isTerrainTree; // Is this Destructible object a stand-in for a terrain tree?
|
||||
[HideInInspector] public AudioClip destroyedSound;
|
||||
[HideInInspector] public AudioClip damagedSound;
|
||||
[HideInInspector] public AudioClip repairedSound;
|
||||
|
||||
// Private variables
|
||||
private const float InvulnerableTimer = 0.5f; // How long (in seconds) the destructible object is invulnerable after instantiation.
|
||||
private DamageLevel _currentDamageLevel;
|
||||
private bool _isInitialized;
|
||||
private float _deactivateTimer;
|
||||
private bool _firstFixedUpdate = true;
|
||||
private Rigidbody _rigidBody; // store a reference to this destructible object's rigidbody, so we don't have to use GetComponent() at runtime.
|
||||
private bool _isInvulnerable; // Determines whether the destructible object starts with a short period of invulnerability. Prevents destructible debris being immediately destroyed by the same forces that destroyed the original object.
|
||||
|
||||
// Properties
|
||||
public bool UseProgressiveDamage { get; set; } = true; // Used to determine if the shader on the destructible object is
|
||||
public bool CheckForClingingDebris { get; set; } = true; // This is an added optimization used when we are auto-pooling destroyed prefabs. It allows us to avoid a GetComponentsInChildren() check for ClingPoints destruction time.
|
||||
public Rigidbody[] PooledRigidbodies { get; set; } // This is an added optimization used when we are auto-pooling destroyed prefabs. It allows us to avoid multiple GetComponentsInChildren() checks for Rigidbodies at destruction time.
|
||||
public GameObject[] PooledRigidbodyGos { get; set; } // This is an added optimization used when we are auto-pooling destroyed prefabs. It allows us to avoid multiple GetComponentsInChildren() checks for the GameObjects on Rigidibodies at destruction time.
|
||||
public float VelocityReduction => Mathf.Abs(velocityReduction - 1f) /* invert the velocity reduction value (so it makes sense in the UI) */;
|
||||
public Quaternion RotationFixedUpdate { get; private set; }
|
||||
public Vector3 PositionFixedUpdate { get; private set; }
|
||||
public Vector3 VelocityFixedUpdate { get; private set; }
|
||||
public Vector3 AngularVelocityFixedUpdate { get; private set; }
|
||||
public float LastRepairedAmount { get; private set; }
|
||||
public float LastDamagedAmount { get; private set; }
|
||||
public float LastDamagedTime { get; private set; }
|
||||
public bool IsDestroyed => !_isInvulnerable && canBeDestroyed && CurrentHitPoints <= 0;
|
||||
public Vector3 MeshCenterPoint { get; private set; }
|
||||
|
||||
// Events
|
||||
public event Action DamagedEvent;
|
||||
public event Action DestroyedEvent;
|
||||
public event Action RepairedEvent;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
CheckForClingingDebris = true;
|
||||
|
||||
if (damageLevels == null || damageLevels.Count == 0)
|
||||
damageLevels = DestructibleHelper.DefaultDamageLevels();
|
||||
damageLevels.CalculateDamageLevels(TotalHitPoints);
|
||||
|
||||
// Store a reference to this object's rigidbody, for better performance.
|
||||
_rigidBody = GetComponent<Rigidbody>();
|
||||
|
||||
// Only calculate the mesh center point if the destructible object uses a fallback particle.
|
||||
if (useFallbackParticle)
|
||||
{
|
||||
MeshRenderer[] meshRenderers = gameObject.GetComponentsInChildren<MeshRenderer>();
|
||||
MeshCenterPoint = gameObject.GetMeshCenterPoint(meshRenderers);
|
||||
if (gameObject.IsAnyMeshPartOfStaticBatch(meshRenderers) && centerPointOverride == Vector3.zero)
|
||||
Debug.Log($"[{gameObject.name}] is a Destructible object with one or more static meshes, but no position override for the fallback particle effect. Particle effect may not spawn where you expect.");
|
||||
}
|
||||
|
||||
PlayDamageEffects();
|
||||
_isInvulnerable = true;
|
||||
Invoke(nameof(RemoveInvulnerability), InvulnerableTimer);
|
||||
|
||||
if (gameObject.HasTagInParent(Tag.TerrainTree))
|
||||
isTerrainTree = true;
|
||||
|
||||
// If AutoPool is turned on, add the destroyed prefab to the ObjectPool.
|
||||
if (autoPoolDestroyedPrefab)
|
||||
ObjectPool.Instance.AddDestructibleObjectToPool(this);
|
||||
|
||||
_isInitialized = true;
|
||||
}
|
||||
|
||||
public void RemoveInvulnerability()
|
||||
{
|
||||
_isInvulnerable = false;
|
||||
}
|
||||
|
||||
public void FixedUpdate()
|
||||
{
|
||||
if (!_isInitialized) return;
|
||||
DestructionManager destructionManager = DestructionManager.Instance;
|
||||
if (destructionManager == null) return;
|
||||
|
||||
// Use the fixed update position/rotation for placement of the destroyed prefab.
|
||||
PositionFixedUpdate = transform.position;
|
||||
RotationFixedUpdate = transform.rotation;
|
||||
if (_rigidBody != null)
|
||||
{
|
||||
VelocityFixedUpdate = _rigidBody.velocity;
|
||||
AngularVelocityFixedUpdate = _rigidBody.angularVelocity;
|
||||
}
|
||||
|
||||
SetDamageLevel();
|
||||
PlayDamageEffects();
|
||||
|
||||
// Check if this script should be auto-deactivated, as configured on the DestructionManager
|
||||
if (destructionManager.autoDeactivateDestructibles && !isTerrainTree && shouldDeactivate)
|
||||
UpdateDeactivation(destructionManager.deactivateAfter);
|
||||
else if (destructionManager.autoDeactivateDestructibleTerrainObjects && isTerrainTree && shouldDeactivate)
|
||||
UpdateDeactivation(destructionManager.deactivateAfter);
|
||||
|
||||
if (IsDestroyed)
|
||||
destructionManager.ProcessDestruction(this, destroyedPrefab, new ExplosiveDamage());
|
||||
|
||||
// If this is the first fixed update frame and autoDeativateDestructibles is true, start this component deactivated.
|
||||
if (_firstFixedUpdate)
|
||||
this.SetActiveOrInactive(destructionManager);
|
||||
|
||||
_firstFixedUpdate = false;
|
||||
}
|
||||
|
||||
private void UpdateDeactivation(float deactivateAfter)
|
||||
{
|
||||
if (_deactivateTimer > deactivateAfter)
|
||||
{
|
||||
_deactivateTimer = 0f;
|
||||
shouldDeactivate = false;
|
||||
enabled = false;
|
||||
}
|
||||
else
|
||||
_deactivateTimer += Time.fixedDeltaTime;
|
||||
}
|
||||
|
||||
/// <summary>Applies a generic amount of damage, with no specific impact or explosive force.</summary>
|
||||
public void ApplyDamage(float amount)
|
||||
{
|
||||
if (IsDestroyed || _isInvulnerable || !DestructionManager.Instance.allowDamage) return; // don't try to apply damage to an already-destroyed or invulnerable object, or if damaging object is not allowed.
|
||||
|
||||
// Adjust the damage based on Min/Max/Time thresholds.
|
||||
if (limitDamage)
|
||||
{
|
||||
if (LastDamagedTime > 0f && minDamageTime > 0f && Time.time < LastDamagedTime + minDamageTime)
|
||||
return;
|
||||
|
||||
if (maxDamage >= 0 && amount > maxDamage)
|
||||
amount = maxDamage;
|
||||
|
||||
if (minDamage >= 0 && minDamage <= maxDamage && amount < minDamage)
|
||||
amount = minDamage;
|
||||
|
||||
if (amount <= 0) return;
|
||||
}
|
||||
|
||||
LastDamagedAmount = amount;
|
||||
LastDamagedTime = Time.time;
|
||||
FireDamagedEvent();
|
||||
|
||||
// Check for any audio clip we may need to play
|
||||
if (damagedSound != null)
|
||||
AudioSource.PlayClipAtPoint(damagedSound, transform.position);
|
||||
|
||||
CurrentHitPoints -= amount;
|
||||
if (CurrentHitPoints > 0) return;
|
||||
if (CurrentHitPoints < 0) CurrentHitPoints = 0;
|
||||
|
||||
PlayDamageEffects();
|
||||
|
||||
if (IsDestroyed)
|
||||
DestructionManager.Instance.ProcessDestruction(this, destroyedPrefab, new DirectDamage{DamageAmount = amount});
|
||||
}
|
||||
|
||||
public void ApplyDamage(Damage damage)
|
||||
{
|
||||
if (IsDestroyed || _isInvulnerable || !DestructionManager.Instance.allowDamage) return; // don't try to apply damage to an already-destroyed or invulnerable object, or if damaging object is not allowed.
|
||||
|
||||
// Adjust the damage based on Min/Max/Time thresholds.
|
||||
if (limitDamage)
|
||||
{
|
||||
if (LastDamagedTime > 0f && minDamageTime > 0f && Time.time < LastDamagedTime + minDamageTime)
|
||||
return;
|
||||
|
||||
if (maxDamage >= 0 && damage.DamageAmount > maxDamage)
|
||||
damage.DamageAmount = maxDamage;
|
||||
|
||||
if (minDamage >= 0 && minDamage <= maxDamage && damage.DamageAmount < minDamage)
|
||||
damage.DamageAmount = minDamage;
|
||||
|
||||
if (damage.DamageAmount <= 0) return;
|
||||
}
|
||||
|
||||
LastDamagedAmount = damage.DamageAmount;
|
||||
LastDamagedTime = Time.time;
|
||||
FireDamagedEvent();
|
||||
|
||||
// Check for any audio clip we may need to play
|
||||
if (damagedSound != null)
|
||||
AudioSource.PlayClipAtPoint(damagedSound, transform.position);
|
||||
|
||||
CurrentHitPoints -= damage.DamageAmount;
|
||||
if (CurrentHitPoints > 0) return;
|
||||
if (CurrentHitPoints < 0) CurrentHitPoints = 0;
|
||||
|
||||
PlayDamageEffects();
|
||||
|
||||
if (IsDestroyed)
|
||||
DestructionManager.Instance.ProcessDestruction(this, destroyedPrefab, damage);
|
||||
}
|
||||
|
||||
public void RepairDamage(float amount)
|
||||
{
|
||||
if (IsDestroyed || !canBeRepaired) return; // object cannot be repaired if it is either already destroyed or not repairable.
|
||||
|
||||
LastRepairedAmount = amount;
|
||||
|
||||
CurrentHitPoints += amount;
|
||||
if (CurrentHitPoints > TotalHitPoints) // object cannot be over-repaired beyond its total hit points.
|
||||
CurrentHitPoints = TotalHitPoints;
|
||||
|
||||
PlayDamageEffects();
|
||||
FireRepairedEvent();
|
||||
|
||||
// Check for any audio clip we may need to play
|
||||
if (repairedSound != null)
|
||||
AudioSource.PlayClipAtPoint(repairedSound, transform.position);
|
||||
}
|
||||
|
||||
public void Destroy()
|
||||
{
|
||||
if (IsDestroyed || _isInvulnerable) return; // don't try to destroy an already-destroyed or invulnerable object.
|
||||
|
||||
LastDamagedAmount = CurrentHitPoints;
|
||||
LastDamagedTime = Time.time;
|
||||
FireDamagedEvent();
|
||||
|
||||
CurrentHitPoints = 0;
|
||||
PlayDamageEffects();
|
||||
|
||||
DestructionManager.Instance.ProcessDestruction(this, destroyedPrefab, CurrentHitPoints);
|
||||
}
|
||||
|
||||
/// <summary>Advances the damage state, applies damage-level materials as needed, and plays particle effects.</summary>
|
||||
private void SetDamageLevel()
|
||||
{
|
||||
DamageLevel damageLevel = damageLevels?.GetDamageLevel(CurrentHitPoints);
|
||||
if (damageLevel == null) return;
|
||||
if (_currentDamageLevel != null && damageLevel == _currentDamageLevel) return;
|
||||
|
||||
_currentDamageLevel = damageLevel;
|
||||
Renderer[] renderers = GetComponentsInChildren<Renderer>();
|
||||
|
||||
foreach (Renderer rend in renderers)
|
||||
{
|
||||
Destructible parentDestructible = rend.GetComponentInParent<Destructible>(); // child Destructible objects should not be affected by damage on their parents.
|
||||
if (parentDestructible != this) continue;
|
||||
bool isAcceptableRenderer = rend is MeshRenderer || rend is SkinnedMeshRenderer;
|
||||
if (isAcceptableRenderer && !rend.gameObject.HasTag(Tag.ClingingDebris) && rend.gameObject.layer != DestructionManager.Instance.debrisLayer)
|
||||
{
|
||||
for (int j = 0; j < rend.sharedMaterials.Length; j++)
|
||||
DestructionManager.Instance.SetProgressiveDamageTexture(rend, rend.sharedMaterials[j], _currentDamageLevel);
|
||||
}
|
||||
}
|
||||
|
||||
PlayDamageEffects();
|
||||
}
|
||||
|
||||
/// <summary>Gets the material to use for the fallback particle effect when this Destructible object is destroyed.</summary>
|
||||
public Material GetDestroyedParticleEffectMaterial()
|
||||
{
|
||||
Renderer[] renderers = GetComponentsInChildren<Renderer>();
|
||||
|
||||
foreach (Renderer rend in renderers)
|
||||
{
|
||||
Destructible parentDestructible = rend.GetComponentInParent<Destructible>(); // only get the material for the parent object to use for a particle effect
|
||||
if (parentDestructible != this) continue;
|
||||
bool isAcceptableRenderer = rend is MeshRenderer || rend is SkinnedMeshRenderer;
|
||||
if (isAcceptableRenderer)
|
||||
return rend.sharedMaterial;
|
||||
}
|
||||
|
||||
return null; // could not find an acceptable material to use for particle effects
|
||||
}
|
||||
|
||||
private void PlayDamageEffects()
|
||||
{
|
||||
// Check if we should play a particle effect for this damage level
|
||||
if (damageEffects == null || damageEffects.Count == 0) return;
|
||||
|
||||
int currentDamageLevelIndex = 0;
|
||||
if (_currentDamageLevel != null)
|
||||
currentDamageLevelIndex = damageLevels.IndexOf(_currentDamageLevel); // FindIndex(a => a == currentDamageLevel);
|
||||
|
||||
foreach (DamageEffect effect in damageEffects)
|
||||
{
|
||||
if (effect == null || effect.Prefab == null) continue;
|
||||
|
||||
// Get rotation
|
||||
Quaternion rotation = transform.rotation;
|
||||
if (effect.Rotation != Vector3.zero)
|
||||
rotation = transform.rotation * Quaternion.Euler(effect.Rotation);
|
||||
|
||||
// Is this effect only played if the destructible object has a certain tag?
|
||||
if (effect.HasTagDependency && !gameObject.HasTag(effect.TagDependency))
|
||||
continue;
|
||||
|
||||
if (_currentDamageLevel != null && effect.TriggeredAt < damageLevels.Count)
|
||||
{
|
||||
// TURN ON pre-destruction damage effects
|
||||
if (currentDamageLevelIndex >= effect.TriggeredAt && !effect.HasStarted)
|
||||
{
|
||||
if (effect.GameObject != null)
|
||||
{
|
||||
for (int i = 0; i < effect.ParticleSystems.Length; i++)
|
||||
{
|
||||
ParticleSystem.EmissionModule emission = effect.ParticleSystems[i].emission;
|
||||
emission.enabled = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// set parent to this destructible object and play
|
||||
effect.GameObject = ObjectPool.Instance.Spawn(effect.Prefab, effect.Offset, rotation, transform);
|
||||
|
||||
if (effect.GameObject != null)
|
||||
{
|
||||
effect.ParticleSystems = effect.GameObject.GetComponentsInChildren<ParticleSystem>();
|
||||
|
||||
if (effect.Scale != Vector3.one)
|
||||
{
|
||||
foreach (ParticleSystem ps in effect.ParticleSystems)
|
||||
{
|
||||
var main = ps.main;
|
||||
main.scalingMode = ParticleSystemScalingMode.Hierarchy;
|
||||
}
|
||||
|
||||
effect.GameObject.transform.localScale = effect.Scale;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
effect.HasStarted = true;
|
||||
}
|
||||
|
||||
// TURN OFF pre-destruction damage effects
|
||||
if (currentDamageLevelIndex < effect.TriggeredAt && effect.HasStarted)
|
||||
{
|
||||
if (effect.GameObject != null)
|
||||
{
|
||||
for (int i = 0; i < effect.ParticleSystems.Length; i++)
|
||||
{
|
||||
ParticleSystem.EmissionModule emission = effect.ParticleSystems[i].emission;
|
||||
emission.enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
effect.HasStarted = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Destroyed effects
|
||||
if (effect.TriggeredAt == damageLevels.Count && IsDestroyed && !effect.HasStarted)
|
||||
{
|
||||
effect.GameObject = canBeDestroyed ?
|
||||
ObjectPool.Instance.Spawn(effect.Prefab, transform.TransformPoint(effect.Offset), rotation) :
|
||||
ObjectPool.Instance.Spawn(effect.Prefab, effect.Offset, rotation, transform);
|
||||
|
||||
if (effect.GameObject != null)
|
||||
{
|
||||
effect.ParticleSystems = effect.GameObject.GetComponentsInChildren<ParticleSystem>();
|
||||
|
||||
if (effect.Scale != Vector3.one)
|
||||
{
|
||||
foreach (ParticleSystem ps in effect.ParticleSystems)
|
||||
{
|
||||
var main = ps.main;
|
||||
main.scalingMode = ParticleSystemScalingMode.Hierarchy;
|
||||
}
|
||||
|
||||
effect.GameObject.transform.localScale = effect.Scale;
|
||||
}
|
||||
}
|
||||
|
||||
effect.HasStarted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: OnCollisionEnter will only fire if a rigidbody is attached to this object!
|
||||
public void OnCollisionEnter(Collision collision)
|
||||
{
|
||||
if (DestructionManager.Instance == null) return;
|
||||
if (!isActiveAndEnabled) return;
|
||||
|
||||
this.ProcessDestructibleCollision(collision, GetComponent<Rigidbody>());
|
||||
|
||||
if (collision.contacts.Length <= 0) return;
|
||||
|
||||
Destructible destructibleObj = collision.contacts[0].otherCollider.gameObject.GetComponentInParent<Destructible>();
|
||||
if (destructibleObj != null && collision.contacts[0].otherCollider.attachedRigidbody == null)
|
||||
destructibleObj.ProcessDestructibleCollision(collision, GetComponent<Rigidbody>());
|
||||
}
|
||||
|
||||
// NOTE: OnDrawGizmos will only fire if Gizmos are turned on in the Unity Editor!
|
||||
public void OnDrawGizmos()
|
||||
{
|
||||
damageEffects.DrawGizmos(transform);
|
||||
centerPointOverride.DrawGizmos(transform);
|
||||
}
|
||||
|
||||
public void FireDestroyedEvent()
|
||||
{
|
||||
DestroyedEvent?.Invoke(); // If there is at least one listener, trigger the event.
|
||||
}
|
||||
|
||||
public void FireRepairedEvent()
|
||||
{
|
||||
RepairedEvent?.Invoke(); // If there is at least one listener, trigger the event.
|
||||
}
|
||||
|
||||
public void FireDamagedEvent()
|
||||
{
|
||||
DamagedEvent?.Invoke(); // If there is at least one listener, trigger the event.
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/Destructible.cs.meta
vendored
Normal file
12
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/Destructible.cs.meta
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b1bbb502083c41048a8fedc6a9693be7
|
||||
timeCreated: 1426551760
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: d4098816c8eb6084296c44408c9fa393, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
26
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/DestructibleParent.cs
vendored
Normal file
26
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/DestructibleParent.cs
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
/// <summary>
|
||||
/// Place this script on a rigidbody parent that has one or more compound collider Destructible children under it.
|
||||
/// Example: the SUV in the showcase demo scene. It is a rigidbody parent but not Destructible itself. But it has many child colliders that are destructible objects.
|
||||
/// </summary>
|
||||
public class DestructibleParent : MonoBehaviour
|
||||
{
|
||||
private void OnCollisionEnter(Collision collision)
|
||||
{
|
||||
if (collision.contacts.Length == 0) return;
|
||||
|
||||
Destructible destructibleObj = collision.contacts[0].thisCollider.gameObject.GetComponentInParent<Destructible>();
|
||||
if (destructibleObj != null)
|
||||
{
|
||||
Rigidbody otherRbody = collision.contacts[0].otherCollider.attachedRigidbody;
|
||||
if (otherRbody != null)
|
||||
destructibleObj.ProcessDestructibleCollision(collision, otherRbody);
|
||||
else
|
||||
destructibleObj.ProcessDestructibleCollision(collision, this.GetComponent<Rigidbody>());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/DestructibleParent.cs.meta
vendored
Normal file
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/DestructibleParent.cs.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8abcb0608c0a3654f97e7a38649246e3
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
30
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/DestructionTest.cs
vendored
Normal file
30
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/DestructionTest.cs
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
/// <summary>
|
||||
/// This script applies damage to all destructible objects in the scene every time you press the "0" key.
|
||||
/// This script is for testing purposes.
|
||||
/// </summary>
|
||||
[DisallowMultipleComponent]
|
||||
public class DestructionTest : MonoBehaviour
|
||||
{
|
||||
public Destructible objectToDestroy;
|
||||
public int damagePerPress = 13; // The amount of damage to apply to all destructible objects per keypress.
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (Input.GetKeyUp("0"))
|
||||
{
|
||||
if (objectToDestroy != null)
|
||||
objectToDestroy.ApplyDamage(damagePerPress);
|
||||
else
|
||||
{
|
||||
Destructible[] destObjs = FindObjectsOfType<Destructible>();
|
||||
foreach (Destructible destObj in destObjs)
|
||||
destObj.ApplyDamage(damagePerPress);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/DestructionTest.cs.meta
vendored
Normal file
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/DestructionTest.cs.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dbcfca89a861f8846959fde873e9142f
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
41
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/EnableColliderAfter.cs
vendored
Normal file
41
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/EnableColliderAfter.cs
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
/// <summary>
|
||||
/// This script is used in conjunction with Object Pooling to enhance performance, in particular with mobile devices.
|
||||
/// This script enables the colliders on a game object over a small amount of time, so the physics load on the CPU is spaced out.
|
||||
/// </summary>
|
||||
public class EnableColliderAfter : MonoBehaviour
|
||||
{
|
||||
public float seconds; // seconds to wait before enabling the collider on this game object.
|
||||
private float timeLeft;
|
||||
private bool isInitialized;
|
||||
|
||||
void Start()
|
||||
{
|
||||
timeLeft = seconds;
|
||||
isInitialized = true;
|
||||
}
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
timeLeft = seconds;
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (!isInitialized) return;
|
||||
|
||||
timeLeft -= Time.deltaTime;
|
||||
if (timeLeft <= 0)
|
||||
{
|
||||
Collider[] colliders = gameObject.GetComponents<Collider>();
|
||||
for (int i = 0; i < colliders.Length; i++)
|
||||
colliders[i].enabled = true;
|
||||
|
||||
Destroy(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/EnableColliderAfter.cs.meta
vendored
Normal file
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/EnableColliderAfter.cs.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 755d107b7f868e84aa09e5429fc073eb
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
44
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/EnableGravityAfter.cs
vendored
Normal file
44
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/EnableGravityAfter.cs
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
/// <summary>
|
||||
/// This script is used in conjunction with Object Pooling to enhance performance, in particular with mobile devices.
|
||||
/// This script enables gravity on a game object's rigidbody over a small amount of time, so the physics load on the CPU is spaced out.
|
||||
/// </summary>
|
||||
public class EnableGravityAfter : MonoBehaviour
|
||||
{
|
||||
public float seconds; // seconds to wait before enabling rigidbody gravity on this game object.
|
||||
private float _timeLeft;
|
||||
private bool _isInitialized;
|
||||
|
||||
void Start()
|
||||
{
|
||||
_timeLeft = seconds;
|
||||
_isInitialized = true;
|
||||
}
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
_timeLeft = seconds;
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (!_isInitialized) return;
|
||||
|
||||
if (GetComponent<Rigidbody>() == null)
|
||||
{
|
||||
Destroy(this);
|
||||
return;
|
||||
}
|
||||
|
||||
_timeLeft -= Time.deltaTime;
|
||||
if (_timeLeft <= 0)
|
||||
{
|
||||
GetComponent<Rigidbody>().useGravity = true;
|
||||
Destroy(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/EnableGravityAfter.cs.meta
vendored
Normal file
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/EnableGravityAfter.cs.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3673fd21a2dbb574d90e88efd449af5f
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
41
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/ExplodeAfter.cs
vendored
Normal file
41
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/ExplodeAfter.cs
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
/// <summary>This script will intantiate the specified explosion prefab after [seconds].</summary>
|
||||
public class ExplodeAfter : MonoBehaviour
|
||||
{
|
||||
[Tooltip("Prefab to instantiate when time runs out.")]
|
||||
public GameObject explosionPrefab;
|
||||
[Tooltip("Seconds to wait before explosion.")]
|
||||
public float seconds = 5f;
|
||||
|
||||
private float _timeLeft;
|
||||
private bool _isInitialized;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
_timeLeft = seconds;
|
||||
_isInitialized = true;
|
||||
}
|
||||
|
||||
public void OnEnable()
|
||||
{
|
||||
_timeLeft = seconds;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (!_isInitialized) return;
|
||||
|
||||
_timeLeft -= Time.deltaTime;
|
||||
if (_timeLeft <= 0)
|
||||
{
|
||||
if (explosionPrefab != null)
|
||||
Instantiate(explosionPrefab, this.transform.position, Quaternion.identity);
|
||||
|
||||
Destroy(this.gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/ExplodeAfter.cs.meta
vendored
Normal file
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/ExplodeAfter.cs.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f82f41d034c9f744e9c7cd51b498250c
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
27
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/FlashingLight.cs
vendored
Normal file
27
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/FlashingLight.cs
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
public class FlashingLight : MonoBehaviour
|
||||
{
|
||||
public float flashInterval = 0.5f;
|
||||
|
||||
private Light _flashingLight;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
_flashingLight = GetComponent<Light>();
|
||||
StartCoroutine(Flashing());
|
||||
}
|
||||
|
||||
private IEnumerator Flashing()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
yield return new WaitForSeconds(flashInterval);
|
||||
_flashingLight.enabled = !_flashingLight.enabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/FlashingLight.cs.meta
vendored
Normal file
13
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/FlashingLight.cs.meta
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 57eaebec4f1ef1d4a83ce16dca58b16d
|
||||
timeCreated: 1525715169
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
27
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/HitEffects.cs
vendored
Normal file
27
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/HitEffects.cs
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
/// <summary>
|
||||
/// This script allows you to assign particle system hit effects for each weapon type.
|
||||
/// PlayEffect() will attempt to play the hit effect for the specified weapon type.
|
||||
/// </summary>
|
||||
[DisallowMultipleComponent]
|
||||
public class HitEffects : MonoBehaviour
|
||||
{
|
||||
public List<HitEffect> effects;
|
||||
|
||||
public void PlayEffect(HitBy weaponType, Vector3 hitPoint, Vector3 hitNormal)
|
||||
{
|
||||
foreach (var eff in effects)
|
||||
{
|
||||
if ((eff.hitBy & weaponType) > 0)
|
||||
{
|
||||
if (eff.effect != null)
|
||||
ObjectPool.Instance.Spawn(eff.effect, hitPoint, Quaternion.LookRotation(hitNormal));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/HitEffects.cs.meta
vendored
Normal file
12
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/HitEffects.cs.meta
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9ae5a7a1942384f45a292ce82d781740
|
||||
timeCreated: 1485105957
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
51
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/PoolAfter.cs
vendored
Normal file
51
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/PoolAfter.cs
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
public class PoolAfter : MonoBehaviour
|
||||
{
|
||||
public float seconds; // seconds to wait before re-pooling this game object.
|
||||
public bool reenableChildren; // determines whether to re-enable all child objects when this object is pooled.
|
||||
public bool removeWhenPooled; // Remove this script when the object is pooled?
|
||||
public bool resetToPrefab; // Reset the entire object back to prefab? (This means it will destroy and recreate the object.)
|
||||
|
||||
private float _timeLeft;
|
||||
private bool _isInitialized;
|
||||
|
||||
void Start()
|
||||
{
|
||||
_timeLeft = seconds;
|
||||
_isInitialized = true;
|
||||
}
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
_timeLeft = seconds;
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (!_isInitialized) return;
|
||||
|
||||
_timeLeft -= Time.deltaTime;
|
||||
if (_timeLeft <= 0)
|
||||
{
|
||||
if (resetToPrefab)
|
||||
{
|
||||
GameObject objectToPool = ObjectPool.Instance.SpawnFromOriginal(this.gameObject.name);
|
||||
if (objectToPool != null)
|
||||
ObjectPool.Instance.PoolObject(objectToPool);
|
||||
|
||||
Destroy(this.gameObject);
|
||||
_isInitialized = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (removeWhenPooled)
|
||||
Destroy(this);
|
||||
|
||||
ObjectPool.Instance.PoolObject(this.gameObject, reenableChildren);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/PoolAfter.cs.meta
vendored
Normal file
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/PoolAfter.cs.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2173075f949abe34cbac509d346178e1
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
42
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/ReleaseObject.cs
vendored
Normal file
42
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/ReleaseObject.cs
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
public class ReleaseObject : MonoBehaviour
|
||||
{
|
||||
public GameObject objectToRelease;
|
||||
public Vector3 angularVelocity;
|
||||
public Vector3 forceToAdd;
|
||||
|
||||
private Vector3 _velocityLastUpdate;
|
||||
|
||||
void Start()
|
||||
{
|
||||
_velocityLastUpdate = GetComponent<Rigidbody>().velocity;
|
||||
}
|
||||
|
||||
void FixedUpdate()
|
||||
{
|
||||
Vector3 velocityChange = (GetComponent<Rigidbody>().velocity - _velocityLastUpdate) / GetComponent<Rigidbody>().mass;
|
||||
|
||||
if (velocityChange.magnitude > .3f && objectToRelease != null)
|
||||
Release();
|
||||
}
|
||||
|
||||
void OnCollisionEnter(Collision collision)
|
||||
{
|
||||
if (collision.relativeVelocity.magnitude > 2f && objectToRelease != null)
|
||||
Release();
|
||||
}
|
||||
|
||||
private void Release()
|
||||
{
|
||||
objectToRelease.GetComponent<Rigidbody>().isKinematic = false;
|
||||
objectToRelease.GetComponent<Rigidbody>().angularVelocity = angularVelocity;
|
||||
objectToRelease.GetComponent<Rigidbody>().WakeUp();
|
||||
if (forceToAdd != Vector3.zero)
|
||||
objectToRelease.GetComponent<Rigidbody>().AddForce(forceToAdd);
|
||||
Destroy(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/ReleaseObject.cs.meta
vendored
Normal file
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/ReleaseObject.cs.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d828c710697789a48952b008bae74122
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
32
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/SpawnObject.cs
vendored
Normal file
32
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/SpawnObject.cs
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
/// <summary>
|
||||
/// This script is used for directly spawning objects into the scene from the Object Pool.
|
||||
/// Simply place this script on an empty gameobject at the same location/rotation you would normally instantiate your prefab.
|
||||
/// Useful for spawning particle effects on destroyed objects.
|
||||
/// </summary>
|
||||
public class SpawnObject : MonoBehaviour
|
||||
{
|
||||
[Tooltip("The prefab of the object you want to spawn into the scene from the object pool.")]
|
||||
public GameObject prefab;
|
||||
|
||||
private ObjectPool _objectPool;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
_objectPool = ObjectPool.Instance;
|
||||
if (_objectPool == null)
|
||||
{
|
||||
Debug.LogWarning("Object Pool was not found or could not be created. Removing script and exiting.");
|
||||
Destroy(this);
|
||||
return;
|
||||
}
|
||||
|
||||
_objectPool.Spawn(prefab, transform.localPosition, transform.localRotation, transform.parent);
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
11
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/SpawnObject.cs.meta
vendored
Normal file
11
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/SpawnObject.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7cbf7229232d1914f9693032f370f1cd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
158
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/StructuralSupport.cs
vendored
Normal file
158
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/StructuralSupport.cs
vendored
Normal file
@@ -0,0 +1,158 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
// ReSharper disable once InlineOutVariableDeclaration
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
/// <summary>
|
||||
/// Put this script on a destroyed object that has debris pieces you want to stay connected together with joints. (Note: if the object is a prefab, unpack it first.)
|
||||
/// The joints this script creates will give your destroyed object's debris pieces structural support until they are destroyed or knocked off by force.
|
||||
/// </summary>
|
||||
public class StructuralSupport : MonoBehaviour
|
||||
{
|
||||
[Tooltip("This is the maximum distance allowed to make a structural support connection. Reduce it if you're getting pieces that float in the air and defy physics. Increase it if too many pieces aren't connecting when they should be.")]
|
||||
public float maxConnectionDistance = 1.25f;
|
||||
|
||||
[Tooltip("The force required to break a joint on the structure. Set to -1 for Infinity.")]
|
||||
public float breakForce = 1250f;
|
||||
|
||||
[Tooltip("The torque required to break a joint on the structure. Set to -1 for Infinity.")]
|
||||
public float breakTorque = 3000f;
|
||||
|
||||
private class StructuralPiece
|
||||
{
|
||||
public GameObject GameObject { get; set; }
|
||||
public Rigidbody Rigidbody { get; set; }
|
||||
public Vector3 CenterPoint { get; set; }
|
||||
}
|
||||
|
||||
public void FixedUpdate()
|
||||
{
|
||||
// Inspect all the joints during every physics loop and remove any that have missing connected rigidbodies
|
||||
FixedJoint[] joints = gameObject.GetComponentsInChildren<FixedJoint>();
|
||||
bool jointsRemoved = false;
|
||||
for (int i = 0; i < joints.Length; i++)
|
||||
{
|
||||
if (joints[i].connectedBody == null)
|
||||
{
|
||||
Destroy(joints[i]); // remove the joint
|
||||
jointsRemoved = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If any joints were removed, wake up the rigidbodies on the object
|
||||
if (jointsRemoved)
|
||||
{
|
||||
Rigidbody[] rbodies = gameObject.GetComponentsInChildren<Rigidbody>();
|
||||
foreach (Rigidbody rbody in rbodies)
|
||||
rbody.WakeUp();
|
||||
}
|
||||
}
|
||||
|
||||
[ExecuteInEditMode]
|
||||
public void AddStructuralSupport()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
List<StructuralPiece> pieces = new List<StructuralPiece>();
|
||||
List<StructuralPiece> otherPieces = new List<StructuralPiece>();
|
||||
|
||||
// First, get a list of all rigidbodies on the object
|
||||
List<Rigidbody> rbodies = gameObject.GetComponentsInChildren<Rigidbody>().ToList();
|
||||
|
||||
// Clear off any old joints on the object so we can create new joint connections.
|
||||
foreach (var comp in gameObject.GetComponentsInChildren<Component>())
|
||||
{
|
||||
if (comp is Joint)
|
||||
DestroyImmediate(comp);
|
||||
}
|
||||
|
||||
// Next, get the mesh centerpoint of each rigidbody's game object
|
||||
foreach (Rigidbody rbody in rbodies)
|
||||
{
|
||||
Vector3 center = Vector3.zero;
|
||||
foreach (Collider coll in rbody.gameObject.GetComponentsInChildren<Collider>())
|
||||
center = center != Vector3.zero ? Vector3.Lerp(center, coll.bounds.center, 0.5f) : coll.bounds.center;
|
||||
|
||||
pieces.Add(new StructuralPiece {
|
||||
GameObject = rbody.gameObject,
|
||||
Rigidbody = rbody,
|
||||
CenterPoint = center
|
||||
});
|
||||
|
||||
otherPieces.Add(new StructuralPiece {
|
||||
GameObject = rbody.gameObject,
|
||||
Rigidbody = rbody,
|
||||
CenterPoint = center
|
||||
});
|
||||
}
|
||||
|
||||
// Now, for each piece, try to linecast from the center of it to the center of every other piece.
|
||||
foreach (StructuralPiece piece in pieces)
|
||||
{
|
||||
for (int i = 0; i < otherPieces.Count; i++)
|
||||
{
|
||||
// skip if this piece is trying to linecast to itself.
|
||||
if (piece.GameObject.GetInstanceID() == otherPieces[i].GameObject.GetInstanceID()) continue;
|
||||
|
||||
// If the connection distance is farther than our threshold will allow, exit.
|
||||
if (Vector3.Distance(piece.CenterPoint, otherPieces[i].CenterPoint) > maxConnectionDistance) continue;
|
||||
|
||||
// Capture the layer this object is on, and move it to the IgnoreRaycast layer temporarily before doing the linecast, so it ignores itself.
|
||||
int originalLayer = piece.GameObject.layer;
|
||||
int ignoreLayer = LayerMask.NameToLayer("Ignore Raycast");
|
||||
piece.GameObject.SetLayerRecursively(ignoreLayer);
|
||||
|
||||
// If we hit a collider while linecasting to the other piece, check it and see if it IS the other piece. If so, that means it's adjacent, and we want to attach a joint connecting the two.
|
||||
RaycastHit hitInfo;
|
||||
if (Physics.Linecast(piece.CenterPoint, otherPieces[i].CenterPoint, out hitInfo))
|
||||
{
|
||||
if (hitInfo.collider.attachedRigidbody == otherPieces[i].Rigidbody)
|
||||
{
|
||||
//Debug.Log($"{piece.GameObject.name} is connected to {otherPieces[i].GameObject.name}");
|
||||
for (int j=0; j<8; j++)
|
||||
Debug.DrawLine(piece.CenterPoint, otherPieces[i].CenterPoint, Color.green, 10f);
|
||||
|
||||
Vector3 midPoint = Vector3.Lerp(piece.CenterPoint, otherPieces[i].CenterPoint, 0.5f);
|
||||
if (breakForce <= -0.1f)
|
||||
breakForce = Single.PositiveInfinity;
|
||||
if (breakTorque <= -0.1f)
|
||||
breakTorque = Single.PositiveInfinity;
|
||||
|
||||
piece.GameObject.AddStiffJoint(otherPieces[i].Rigidbody, midPoint, Vector3.zero, breakForce, breakTorque);
|
||||
}
|
||||
}
|
||||
|
||||
// Set the layer on the piece back to what it was originally
|
||||
piece.GameObject.SetLayerRecursively(originalLayer);
|
||||
}
|
||||
|
||||
// Remove this piece from the "other pieces" to check
|
||||
otherPieces.RemoveAll(x => x.GameObject.GetInstanceID() == piece.GameObject.GetInstanceID());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
[ExecuteInEditMode]
|
||||
public void RemoveStructuralSupport()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
FixedJoint[] joints = gameObject.GetComponentsInChildren<FixedJoint>();
|
||||
for (int i = 0; i < joints.Length; i++)
|
||||
DestroyImmediate(joints[i]); // remove the joint
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
public static class LayerExtensions
|
||||
{
|
||||
public static void SetLayerRecursively(this GameObject obj, int layer)
|
||||
{
|
||||
obj.layer = layer;
|
||||
|
||||
foreach (Transform child in obj.transform)
|
||||
child.gameObject.SetLayerRecursively(layer);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/StructuralSupport.cs.meta
vendored
Normal file
11
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/StructuralSupport.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7da473fd710ae3e4ea5a6bfed246029a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
68
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/SupportPoint.cs
vendored
Normal file
68
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/SupportPoint.cs
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
/// <summary>
|
||||
/// This script manages a single support point (a Trigger Collider) on an object.
|
||||
/// On startup, if the support point is connected to another rigidbody, it will create a custom joint connecting the two.
|
||||
/// </summary>
|
||||
public class SupportPoint : MonoBehaviour
|
||||
{
|
||||
public int breakForce = 750;
|
||||
public int breakTorque = 750;
|
||||
|
||||
private bool _canSupport = true;
|
||||
|
||||
void Start()
|
||||
{
|
||||
if (transform.parent == null)
|
||||
{
|
||||
Debug.Log("[" + name + "] has no parent. Support points are designed to be children of objects that have attached colliders.");
|
||||
_canSupport = false;
|
||||
}
|
||||
else if (transform.parent.GetComponent<Collider>() == null || !transform.parent.GetComponent<Collider>().enabled)
|
||||
{
|
||||
Debug.Log("[" + transform.parent.name + "] has a support point but no enabled collider. Support points only work on objects with colliders.");
|
||||
_canSupport = false;
|
||||
}
|
||||
else if (transform.parent.GetComponent<Collider>().attachedRigidbody == null)
|
||||
{
|
||||
Debug.Log("[" + transform.parent.name + "] has a support point but no attached rigidbody. Support points only work on objects with rigidbodies.");
|
||||
_canSupport = false;
|
||||
}
|
||||
|
||||
if (_canSupport)
|
||||
{
|
||||
Ray ray = new Ray(transform.position - (transform.forward * 0.025f), transform.forward); // need to start the ray behind the transform a little
|
||||
//Debug.DrawRay(this.transform.position, this.transform.forward * .15f, Color.red, 10f);
|
||||
RaycastHit[] hitInfo = Physics.RaycastAll(ray, 0.075f);
|
||||
|
||||
for(int i=0; i<hitInfo.Length; i++)
|
||||
{
|
||||
// ignore colliders without rigidbodies to attach a joint to.
|
||||
if (hitInfo[i].collider.attachedRigidbody == null) continue;
|
||||
|
||||
// ignore other trigger colliders - we only want to attach to the parent object.
|
||||
if (hitInfo[i].collider.isTrigger) continue;
|
||||
|
||||
// Get the forward angle, as it relates to the parent
|
||||
Vector3 angleAxis = transform.parent.transform.InverseTransformDirection(transform.TransformDirection(Vector3.forward));
|
||||
|
||||
// Add a stiff joint for support.
|
||||
transform.parent.GetComponent<Collider>().attachedRigidbody.gameObject.AddStiffJoint(hitInfo[i].collider.attachedRigidbody,
|
||||
transform.localPosition, angleAxis, breakForce, breakTorque);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Destroy(gameObject);
|
||||
}
|
||||
|
||||
private void OnDrawGizmos()
|
||||
{
|
||||
Gizmos.color = Color.yellow;
|
||||
Gizmos.DrawWireSphere(transform.position - (transform.forward * 0.025f), .01f);
|
||||
Gizmos.DrawRay(transform.position - (transform.forward * 0.025f), transform.forward * 0.075f);
|
||||
}
|
||||
}
|
||||
}
|
||||
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/SupportPoint.cs.meta
vendored
Normal file
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/SupportPoint.cs.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d131f47680139ef448bbf60c9da110a8
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
44
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/TagAfter.cs
vendored
Normal file
44
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/TagAfter.cs
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
/// <summary>
|
||||
/// This script tags all colliders on the object after X seconds. It is used to tag colliders on destroyed object
|
||||
/// debris with minimal performance impact.
|
||||
/// </summary>
|
||||
public class TagAfter : MonoBehaviour
|
||||
{
|
||||
public float seconds = 1f; // seconds to wait before tagging all colliders under this game object.
|
||||
public Tag tagWith; // what to tag all colliders under this game object with.
|
||||
|
||||
private float _timeLeft;
|
||||
private bool _isInitialized;
|
||||
|
||||
void Start()
|
||||
{
|
||||
_timeLeft = seconds;
|
||||
_isInitialized = true;
|
||||
}
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
_timeLeft = seconds;
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (!_isInitialized) return;
|
||||
|
||||
_timeLeft -= Time.deltaTime;
|
||||
if (_timeLeft <= 0)
|
||||
{
|
||||
Collider[] colls = this.gameObject.GetComponentsInChildren<Collider>();
|
||||
for (int i = 0; i < colls.Length; i++)
|
||||
colls[i].gameObject.AddTag(tagWith);
|
||||
|
||||
Destroy(this);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/TagAfter.cs.meta
vendored
Normal file
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/TagAfter.cs.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4153d7ec8f83d1a448229ed26f28814a
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
26
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/TagIt.cs
vendored
Normal file
26
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/TagIt.cs
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
// ReSharper disable InconsistentNaming
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
/// <summary>
|
||||
/// TagIt is a system that allows you to mark objects with multiple tags. It is used by DestroyIt to keep track of debris,
|
||||
/// destructible groups, cling points, etc.
|
||||
/// If you are using TagIt to specify hit effects on a destructible object, you should use the HitEffects script instead.
|
||||
/// </summary>
|
||||
[DisallowMultipleComponent]
|
||||
public class TagIt : MonoBehaviour
|
||||
{
|
||||
public List<Tag> tags;
|
||||
|
||||
public void OnEnable()
|
||||
{
|
||||
if (tags == null)
|
||||
tags = new List<Tag>();
|
||||
|
||||
if (tags.Count == 0)
|
||||
tags.Add(Tag.Untagged);
|
||||
}
|
||||
}
|
||||
}
|
||||
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/TagIt.cs.meta
vendored
Normal file
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/TagIt.cs.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d3dbf5a679affaa4f8cdc6a7adcd4e4b
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
62
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/TerrainPreserver.cs
vendored
Normal file
62
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/TerrainPreserver.cs
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[DisallowMultipleComponent]
|
||||
public class TerrainPreserver : MonoBehaviour
|
||||
{
|
||||
public void Awake ()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (Application.isPlaying) return;
|
||||
|
||||
// Get the terrain to try to preserve.
|
||||
TreeManager treeManager = gameObject.GetComponent<TreeManager>();
|
||||
if (treeManager == null) return;
|
||||
|
||||
Terrain terrain = treeManager.terrain;
|
||||
if (terrain == null)
|
||||
terrain = Terrain.activeTerrain;
|
||||
if (terrain == null) return;
|
||||
|
||||
// Check to see if a terrainData backup exists.
|
||||
string terrainDataPath = AssetDatabase.GetAssetPath(terrain.terrainData);
|
||||
string terrainDataBkpPath = terrainDataPath.Replace(".asset", "") + "_bkp.asset";
|
||||
TerrainData terrainDataBkp = AssetDatabase.LoadAssetAtPath<TerrainData>(terrainDataBkpPath);
|
||||
|
||||
// If a terrainData backup exists, ask the user if they want to restore tree data from the backup.
|
||||
if (terrainDataBkp != null)
|
||||
{
|
||||
int option = EditorUtility.DisplayDialogComplex("Restore Terrain Trees from Backup?",
|
||||
"The Unity Editor may not have shut down correctly last time, which could mean destructible terrain trees were removed from terrain [" + terrain.terrainData.name + "]. Fortunately, there is a backup.\n\n" +
|
||||
"Choose 'Restore' to restore trees from the backup. Choose 'Don't Restore' to keep existing trees as they are " +
|
||||
"and delete the backup. Choose 'Ask Later' to do nothing right now, so you can inspect your terrain and make the decision later.",
|
||||
"Restore", "Ask Later", "Don't Restore");
|
||||
|
||||
switch (option)
|
||||
{
|
||||
// Restore trees from backup
|
||||
case 0:
|
||||
terrain.terrainData.treeInstances = terrainDataBkp.treeInstances;
|
||||
AssetDatabase.DeleteAsset(terrainDataBkpPath);
|
||||
Debug.Log("Tree instances restored on [" + terrain.terrainData.name + "].");
|
||||
break;
|
||||
// Don't do anything - the user will be prompted again next time this script runs
|
||||
case 1:
|
||||
break;
|
||||
// Don't restore trees and delete backup
|
||||
case 2:
|
||||
AssetDatabase.DeleteAsset(terrainDataBkpPath);
|
||||
break;
|
||||
default:
|
||||
Debug.LogError("Unrecognized option.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
11
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/TerrainPreserver.cs.meta
vendored
Normal file
11
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/TerrainPreserver.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 33d5c334120e92b46b6b3d17525d6e80
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
35
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/WhenDamaged.cs
vendored
Normal file
35
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/WhenDamaged.cs
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
/// <summary>
|
||||
/// This is a helper script that listens to a Destructible object's DamagedEvent and runs additional code when the object is damaged.
|
||||
/// Put this script on a GameObject that has the Destructible script.
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(Destructible))]
|
||||
public class WhenDamaged : MonoBehaviour
|
||||
{
|
||||
private Destructible _destObj;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
// Try to get the Destructible script on the object. If found, attach the OnDamaged event listener to the DamagedEvent.
|
||||
_destObj = gameObject.GetComponent<Destructible>();
|
||||
if (_destObj != null)
|
||||
_destObj.DamagedEvent += OnDamaged;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
// Unregister the event listener when disabled/destroyed. Very important to prevent memory leaks due to orphaned event listeners!
|
||||
if (_destObj == null) return;
|
||||
_destObj.DamagedEvent -= OnDamaged;
|
||||
}
|
||||
|
||||
/// <summary>When the Destructible object is damaged, the code in this method will run.</summary>
|
||||
private void OnDamaged()
|
||||
{
|
||||
Debug.Log($"{_destObj.name} was damaged for {_destObj.LastDamagedAmount} hit points");
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/WhenDamaged.cs.meta
vendored
Normal file
12
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/WhenDamaged.cs.meta
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 34ffae2eac105914e83a47dd47709e7d
|
||||
timeCreated: 1480569302
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
43
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/WhenDamagedDamageParents.cs
vendored
Normal file
43
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/WhenDamagedDamageParents.cs
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
/// <summary>
|
||||
/// Put this script on a GameObject that has the Destructible script.
|
||||
/// When this object is damaged, it will also apply that damage to all of its parent Destructible objects.
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(Destructible))]
|
||||
public class WhenDamagedDamageParents : MonoBehaviour
|
||||
{
|
||||
private Destructible _destObj;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
// Try to get the Destructible script on the object. If found, attach the OnDamaged event listener to the DamagedEvent.
|
||||
_destObj = gameObject.GetComponent<Destructible>();
|
||||
if (_destObj != null)
|
||||
_destObj.DamagedEvent += OnDamaged;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
// Unregister the event listener when disabled/destroyed. Very important to prevent memory leaks due to orphaned event listeners!
|
||||
if (_destObj == null) return;
|
||||
_destObj.DamagedEvent -= OnDamaged;
|
||||
}
|
||||
|
||||
/// <summary>When the Destructible object is damaged, the code in this method will run.</summary>
|
||||
private void OnDamaged()
|
||||
{
|
||||
// Get a reference to all the Destructible parents of this object
|
||||
Destructible[] destructibleParents = gameObject.GetComponentsInParent<Destructible>();
|
||||
|
||||
// Loop through the destructible parent objects and apply damage
|
||||
for (int i = 0; i < destructibleParents.Length; i++)
|
||||
{
|
||||
if (destructibleParents[i] == _destObj) continue; // Ignore the current destructible object
|
||||
destructibleParents[i].ApplyDamage(_destObj.LastDamagedAmount); // Apply the damage to only parent objects
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/WhenDamagedDamageParents.cs.meta
vendored
Normal file
11
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/WhenDamagedDamageParents.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3a49aec3c54ac8344acb427b9a830442
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
35
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/WhenDestroyed.cs
vendored
Normal file
35
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/WhenDestroyed.cs
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
/// <summary>
|
||||
/// This is a helper script that listens to a Destructible object's DestroyedEvent and runs additional code when the object is destroyed.
|
||||
/// Put this script on a GameObject that has the Destructible script.
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(Destructible))]
|
||||
public class WhenDestroyed : MonoBehaviour
|
||||
{
|
||||
private Destructible _destObj;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
// Try to get the Destructible script on the object. If found, attach the OnDestroyed event listener to the DestroyedEvent.
|
||||
_destObj = gameObject.GetComponent<Destructible>();
|
||||
if (_destObj != null)
|
||||
_destObj.DestroyedEvent += OnDestroyed;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
// Unregister the event listener when disabled/destroyed. Very important to prevent memory leaks due to orphaned event listeners!
|
||||
if (_destObj == null) return;
|
||||
_destObj.DestroyedEvent -= OnDestroyed;
|
||||
}
|
||||
|
||||
/// <summary>When the Destructible object is destroyed, the code in this method will run.</summary>
|
||||
private void OnDestroyed()
|
||||
{
|
||||
Debug.Log($"{_destObj.name} was destroyed at world coordinates: {_destObj.transform.position}");
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/WhenDestroyed.cs.meta
vendored
Normal file
12
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/WhenDestroyed.cs.meta
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ec03d957467764141969df91f9a37fcc
|
||||
timeCreated: 1461724580
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
41
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/WhenDestroyedPlaySound.cs
vendored
Normal file
41
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/WhenDestroyedPlaySound.cs
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
/// <summary>
|
||||
/// This is a helper script that listens to a Destructible object's DestroyedEvent and plays a sound when the object is destroyed.
|
||||
/// Put this script on a GameObject that has the Destructible script.
|
||||
/// </summary>
|
||||
public class WhenDestroyedPlaySound : MonoBehaviour
|
||||
{
|
||||
public AudioClip clip;
|
||||
private Destructible _destObj;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
// Try to get the Destructible script on the object. If found, attach the OnDestroyed event listener to the DestroyedEvent.
|
||||
_destObj = gameObject.GetComponent<Destructible>();
|
||||
if (_destObj != null)
|
||||
_destObj.DestroyedEvent += OnDestroyed;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
// Unregister the event listener when disabled/destroyed. Very important to prevent memory leaks due to orphaned event listeners!
|
||||
if (_destObj == null) return;
|
||||
_destObj.DestroyedEvent -= OnDestroyed;
|
||||
}
|
||||
|
||||
/// <summary>When the Destructible object is destroyed, the code in this method will run.</summary>
|
||||
private void OnDestroyed()
|
||||
{
|
||||
// Create a new game object to play the audio clip, and position it at the destroyed game object's location.
|
||||
var audioObj = new GameObject("Audio Source");
|
||||
audioObj.transform.position = _destObj.transform.position;
|
||||
var audioSource = audioObj.AddComponent<AudioSource>();
|
||||
var destroyAfter = audioObj.AddComponent<DestroyAfter>();
|
||||
destroyAfter.seconds = 5f; // Destroy the audio source object after X seconds.
|
||||
audioSource.PlayOneShot(clip); // Play the audio clip.
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/WhenDestroyedPlaySound.cs.meta
vendored
Normal file
12
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/WhenDestroyedPlaySound.cs.meta
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dc8c9d2635bcc244b8a6753462da6f74
|
||||
timeCreated: 1463421045
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
49
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/WhenDestroyedResetTree.cs
vendored
Normal file
49
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/WhenDestroyedResetTree.cs
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
/// <summary>
|
||||
/// This is a helper script that listens to a Destructible object's DestroyedEvent and runs additional code when the object is destroyed.
|
||||
/// Put this script on a GameObject that has the Destructible script.
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(Destructible))]
|
||||
public class WhenDestroyedResetTree : MonoBehaviour
|
||||
{
|
||||
[Tooltip("How many seconds to wait before resetting the tree.")]
|
||||
public float resetAfterSeconds = 30f;
|
||||
private Destructible _destObj;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
// Try to get the Destructible script on the object. If found, attach the OnDestroyed event listener to the DestroyedEvent.
|
||||
_destObj = gameObject.GetComponent<Destructible>();
|
||||
if (_destObj != null)
|
||||
_destObj.DestroyedEvent += OnDestroyed;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
// Unregister the event listener when disabled/destroyed. Very important to prevent memory leaks due to orphaned event listeners!
|
||||
if (_destObj == null) return;
|
||||
_destObj.DestroyedEvent -= OnDestroyed;
|
||||
}
|
||||
|
||||
/// <summary>When the Destructible object is destroyed, the code in this method will run.</summary>
|
||||
private void OnDestroyed()
|
||||
{
|
||||
Debug.Log($"{_destObj.name} was destroyed at world coordinates: {_destObj.transform.position}");
|
||||
TerrainTree terrainTree = Terrain.activeTerrain.ClosestTreeToPoint(transform.position);
|
||||
TreeReset tree = new TreeReset()
|
||||
{
|
||||
prototypeIndex = terrainTree.TreeInstance.prototypeIndex,
|
||||
position = terrainTree.TreeInstance.position,
|
||||
color = terrainTree.TreeInstance.color,
|
||||
heightScale = terrainTree.TreeInstance.heightScale,
|
||||
widthScale = terrainTree.TreeInstance.widthScale,
|
||||
resetTime = DateTime.Now.AddSeconds(resetAfterSeconds)
|
||||
};
|
||||
TreeManager.Instance.treesToReset.Add(tree);
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/WhenDestroyedResetTree.cs.meta
vendored
Normal file
3
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/WhenDestroyedResetTree.cs.meta
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2c2ddca75a0e4e2e9a76326cb378bb42
|
||||
timeCreated: 1549237993
|
||||
35
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/WhenRepaired.cs
vendored
Normal file
35
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/WhenRepaired.cs
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
/// <summary>
|
||||
/// This is a helper script that listens to a Destructible object's RepairedEvent and runs additional code when the object is repaired.
|
||||
/// Put this script on a GameObject that has the Destructible script.
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(Destructible))]
|
||||
public class WhenRepaired : MonoBehaviour
|
||||
{
|
||||
private Destructible _destObj;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
// Try to get the Destructible script on the object. If found, attach the OnRepaired event listener to the RepairedEvent.
|
||||
_destObj = gameObject.GetComponent<Destructible>();
|
||||
if (_destObj != null)
|
||||
_destObj.RepairedEvent += OnRepaired;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
// Unregister the event listener when disabled/destroyed. Very important to prevent memory leaks due to orphaned event listeners!
|
||||
if (_destObj == null) return;
|
||||
_destObj.RepairedEvent -= OnRepaired;
|
||||
}
|
||||
|
||||
/// <summary>When the Destructible object is repaired, the code in this method will run.</summary>
|
||||
private void OnRepaired()
|
||||
{
|
||||
Debug.Log($"{_destObj.name} was repaired {_destObj.LastRepairedAmount} hit points");
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/WhenRepaired.cs.meta
vendored
Normal file
12
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Behaviors/WhenRepaired.cs.meta
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3b10107f86c0c6543a3256ef38b80d00
|
||||
timeCreated: 1476058790
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
3
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Destroyit.Runtime.asmdef
vendored
Normal file
3
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Destroyit.Runtime.asmdef
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"name": "Destroy.Runtime"
|
||||
}
|
||||
7
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Destroyit.Runtime.asmdef.meta
vendored
Normal file
7
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Destroyit.Runtime.asmdef.meta
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3a5d3214f3d7fb845bf8991981763e58
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
17
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Extensions.meta
vendored
Normal file
17
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Extensions.meta
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 46b9e9b3a1e926c4eac2be881a4c08e6
|
||||
labels:
|
||||
- Destruction
|
||||
- Destroy
|
||||
- Physics
|
||||
- DestroyIt
|
||||
- Damage
|
||||
- Fracturing
|
||||
- Demolition
|
||||
folderAsset: yes
|
||||
timeCreated: 1427397479
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
39
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Extensions/ArrayExtensions.cs
vendored
Normal file
39
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Extensions/ArrayExtensions.cs
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
public static class ArrayExtensions
|
||||
{
|
||||
/// <summary>Provides a quick way to remove elements from a standard array.</summary>
|
||||
public static T[] RemoveAllAt<T>(this T[] array, int[] removeIndices)
|
||||
{
|
||||
T[] newArray = new T[0];
|
||||
|
||||
if (removeIndices.Length == 0) return array;
|
||||
if (removeIndices.Length >= array.Length) return newArray;
|
||||
|
||||
newArray = new T[array.Length];
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int itemsKept = 0;
|
||||
while (i < array.Length)
|
||||
{
|
||||
bool keepItem = true;
|
||||
for (int x = 0; x < removeIndices.Length; x++)
|
||||
{
|
||||
if (i == removeIndices[x])
|
||||
keepItem = false;
|
||||
}
|
||||
if (keepItem)
|
||||
{
|
||||
itemsKept++;
|
||||
newArray[j] = array[i];
|
||||
j++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
Array.Resize(ref newArray, itemsKept);
|
||||
return newArray;
|
||||
}
|
||||
}
|
||||
}
|
||||
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Extensions/ArrayExtensions.cs.meta
vendored
Normal file
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Extensions/ArrayExtensions.cs.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bbde6c1a812a73349864180510448026
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
233
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Extensions/DestructibleExtensions.cs
vendored
Normal file
233
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Extensions/DestructibleExtensions.cs
vendored
Normal file
@@ -0,0 +1,233 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor.SceneManagement;
|
||||
#endif
|
||||
// ReSharper disable ForCanBeConvertedToForeach
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
public static class DestructionExtensions
|
||||
{
|
||||
public static void Update(this List<float> models, int withinSeconds)
|
||||
{
|
||||
bool isChanged = false;
|
||||
if (models.Count > 0)
|
||||
{
|
||||
for (int i = 0; i < models.Count; i++)
|
||||
{
|
||||
if (Time.time > (models[i] + withinSeconds))
|
||||
{
|
||||
models.Remove(models[i]);
|
||||
isChanged = true;
|
||||
}
|
||||
}
|
||||
if (isChanged)
|
||||
DestructionManager.Instance.FireDestroyedPrefabCounterChangedEvent();
|
||||
}
|
||||
}
|
||||
|
||||
public static void ReleaseClingingDebris(this Destructible destroyedObj)
|
||||
{
|
||||
List<Transform> clingingDebris = new List<Transform>();
|
||||
TagIt[] tagIts = destroyedObj.GetComponentsInChildren<TagIt>();
|
||||
if (tagIts == null) return;
|
||||
|
||||
for (int i = 0; i < tagIts.Length; i++)
|
||||
{
|
||||
for (int j = 0; j < tagIts[i].tags.Count; j++)
|
||||
{
|
||||
if (tagIts[i].tags[j] == Tag.ClingingDebris)
|
||||
clingingDebris.Add(tagIts[i].transform);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < clingingDebris.Count; i++)
|
||||
{
|
||||
//TODO: When releasing clinging debris, we need to add back the same rigidbody configuration the object had before becoming debris.
|
||||
clingingDebris[i].gameObject.AddComponent<Rigidbody>();
|
||||
}
|
||||
}
|
||||
|
||||
public static void MakeDebrisCling(this GameObject destroyedObj)
|
||||
{
|
||||
// Check to see if any debris pieces will be clinging to nearby rigidbodies
|
||||
ClingPoint[] clingPoints = destroyedObj.GetComponentsInChildren<ClingPoint>();
|
||||
for (int i=0; i<clingPoints.Length; i++)
|
||||
{
|
||||
Rigidbody clingPointRbody = clingPoints[i].transform.parent.GetComponent<Rigidbody>();
|
||||
if (clingPointRbody == null) continue;
|
||||
|
||||
// Check percent chance first
|
||||
if (clingPoints[i].chanceToCling < 100) // 100% chance always clings
|
||||
{
|
||||
int randomNbr = Random.Range(1, 100);
|
||||
if (randomNbr > clingPoints[i].chanceToCling) // exit if random number is outside the possible chance.
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if there's anything to cling to.
|
||||
Ray ray = new Ray(clingPoints[i].transform.position - (clingPoints[i].transform.forward * 0.025f), clingPoints[i].transform.forward); // need to start the ray behind the transform a little
|
||||
RaycastHit hitInfo;
|
||||
if (Physics.Raycast(ray, out hitInfo, 0.075f))
|
||||
{
|
||||
if (hitInfo.collider.isTrigger) continue; // ignore trigger colliders.
|
||||
|
||||
clingPointRbody.transform.parent = hitInfo.collider.gameObject.transform;
|
||||
|
||||
// If the debris is Destructible, add DestructibleParent script to the parent so debris will get OnCollisionEnter() events.
|
||||
if (clingPointRbody.gameObject.GetComponent<Destructible>() && !hitInfo.collider.gameObject.GetComponent<DestructibleParent>())
|
||||
hitInfo.collider.gameObject.AddComponent<DestructibleParent>();
|
||||
|
||||
// If the object this debris is clinging to is also destructible, set it up so it will be released when the parent object is destroyed.
|
||||
Destructible destructibleObj = hitInfo.collider.gameObject.GetComponentInParent<Destructible>();
|
||||
if (destructibleObj != null)
|
||||
{
|
||||
destructibleObj.unparentOnDestroy.Add(clingPointRbody.gameObject);
|
||||
DelayedRigidbody delayedRbody = clingPointRbody.gameObject.AddComponent<DelayedRigidbody>();
|
||||
delayedRbody.mass = clingPointRbody.mass;
|
||||
delayedRbody.drag = clingPointRbody.drag;
|
||||
delayedRbody.angularDrag = clingPointRbody.angularDrag;
|
||||
}
|
||||
// Remove all cling points from this clinging debris object
|
||||
ClingPoint[] clingPointsToDestroy = clingPointRbody.gameObject.GetComponentsInChildren<ClingPoint>();
|
||||
for (int j = 0; j < clingPointsToDestroy.Length; j++)
|
||||
Object.Destroy(clingPointsToDestroy[j].gameObject);
|
||||
|
||||
// Remove all rigidbodies from this clinging debris object
|
||||
clingPointRbody.gameObject.RemoveAllFromChildren<Rigidbody>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void ProcessDestructibleCollision(this Destructible destructibleObj, Collision collision, Rigidbody collidingRigidbody)
|
||||
{
|
||||
// Ignore collisions if collidingRigidbody is null
|
||||
if (collidingRigidbody == null) return;
|
||||
|
||||
// Check for DontDoDamage tag on the collidingRigidbody
|
||||
if (collidingRigidbody.gameObject.HasTag(Tag.DontDoDamage)) return;
|
||||
|
||||
// Ignore collisions if this object is destroyed.
|
||||
if (destructibleObj.IsDestroyed) return;
|
||||
|
||||
// Check that the impact is forceful enough to cause damage
|
||||
if (collision.relativeVelocity.magnitude < destructibleObj.ignoreCollisionsUnder) return;
|
||||
|
||||
if (collision.contacts.Length == 0) return;
|
||||
|
||||
float impactDamage;
|
||||
Rigidbody otherRbody = collision.contacts[0].otherCollider.gameObject.GetComponentInParent<Rigidbody>(true);
|
||||
|
||||
// If we've collided with another rigidbody, use the average mass of the two objects for impact damage.
|
||||
if (otherRbody != null)
|
||||
{
|
||||
if (otherRbody.gameObject.HasTag(Tag.DontDoDamage)) return;
|
||||
float avgMass = (otherRbody.mass + collidingRigidbody.mass) / 2;
|
||||
impactDamage = Vector3.Dot(collision.contacts[0].normal, collision.relativeVelocity) * avgMass;
|
||||
}
|
||||
else // If we've collided with a static object (terrain, static collider, etc), use this object's attached rigidbody.
|
||||
{
|
||||
Rigidbody rbody = destructibleObj.GetComponent<Rigidbody>();
|
||||
impactDamage = Vector3.Dot(collision.contacts[0].normal, collision.relativeVelocity) * collidingRigidbody.mass;
|
||||
}
|
||||
|
||||
impactDamage = Mathf.Abs(impactDamage); // can't have negative damage
|
||||
|
||||
if (impactDamage > 1f) // impact must do at least 1 damage to bother with.
|
||||
{
|
||||
//Debug.Log("Impact Damage: " + impactDamage);
|
||||
//Debug.DrawRay(otherRbody.transform.position, collision.relativeVelocity, Color.yellow, 10f); // yellow: where the impact force is heading
|
||||
ImpactDamage impactInfo = new ImpactDamage() { ImpactObject = otherRbody, DamageAmount = impactDamage, ImpactObjectVelocityFrom = collision.relativeVelocity * -1 };
|
||||
destructibleObj.ApplyDamage(impactInfo);
|
||||
}
|
||||
}
|
||||
|
||||
public static void CalculateDamageLevels(this List<DamageLevel> damageLevels, float maxHitPoints)
|
||||
{
|
||||
if (maxHitPoints <= 0) { return; }
|
||||
if (damageLevels == null || damageLevels.Count == 0) { return; }
|
||||
|
||||
// Sort the list descending on Damage Percent field.
|
||||
//damageLevels.Sort((x, y) => -1 * x.damagePercent.CompareTo(y.damagePercent));
|
||||
|
||||
int prevHealthPercent = -1;
|
||||
for (int i = 0; i < damageLevels.Count; i++)
|
||||
{
|
||||
if (damageLevels[i] == null) continue;
|
||||
if (damageLevels[i].healthPercent <= 0)
|
||||
{
|
||||
damageLevels[i].hasError = true;
|
||||
continue;
|
||||
}
|
||||
if (prevHealthPercent > -1 && damageLevels[i].healthPercent >= prevHealthPercent)
|
||||
{
|
||||
damageLevels[i].hasError = true;
|
||||
prevHealthPercent = damageLevels[i].healthPercent;
|
||||
continue; // Health percents should go down with every subsequent damage level.
|
||||
}
|
||||
|
||||
damageLevels[i].hasError = false;
|
||||
if (i == 0) // highest damage level, set max hit points to maxHitPoints of destructible object.
|
||||
damageLevels[i].maxHitPoints = maxHitPoints;
|
||||
else // not the highest damage level, so set the previous level's minHitPoints to this level's maxHitPoints.
|
||||
{
|
||||
damageLevels[i].maxHitPoints = maxHitPoints * (.01f * damageLevels[i].healthPercent);
|
||||
damageLevels[i - 1].minHitPoints = maxHitPoints * (.01f * damageLevels[i].healthPercent) + .1f;
|
||||
}
|
||||
if (i == damageLevels.Count - 1) // lowest damage level, set min hit point range to 0.
|
||||
damageLevels[i].minHitPoints = 0;
|
||||
|
||||
prevHealthPercent = damageLevels[i].healthPercent;
|
||||
}
|
||||
}
|
||||
|
||||
public static DamageLevel GetDamageLevel(this List<DamageLevel> damageLevels, float hitPoints)
|
||||
{
|
||||
if (damageLevels == null || damageLevels.Count == 0) return null;
|
||||
|
||||
if (hitPoints <= 0)
|
||||
return damageLevels[damageLevels.Count - 1];
|
||||
|
||||
for (int i = 0; i < damageLevels.Count; i++)
|
||||
{
|
||||
if (damageLevels[i].maxHitPoints >= hitPoints && damageLevels[i].minHitPoints <= hitPoints)
|
||||
return damageLevels[i];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void ReparentChildren(this Destructible destObj, GameObject newObj)
|
||||
{
|
||||
if (destObj.childrenToReParentByName != null)
|
||||
{
|
||||
if (destObj.childrenToReParentByName.Count > 0)
|
||||
{
|
||||
foreach (string childName in destObj.childrenToReParentByName)
|
||||
{
|
||||
Transform child = destObj.transform.Find(childName);
|
||||
if (child != null)
|
||||
child.SetParent(newObj.transform);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>If autoDeativateDestructibles is set to true on DestructionManager, start the Destructible component deactivated.</summary>
|
||||
/// <remarks>Very useful for trees and other terrain objects, makes performance better.</remarks>
|
||||
public static void SetActiveOrInactive(this Destructible destObj, DestructionManager destructionManager)
|
||||
{
|
||||
if (!destObj.isTerrainTree) // non-terrain tree destructibles
|
||||
{
|
||||
if (destructionManager.autoDeactivateDestructibles)
|
||||
destObj.enabled = false;
|
||||
}
|
||||
else // terrain tree destructibles
|
||||
{
|
||||
if (destructionManager.autoDeactivateDestructibleTerrainObjects)
|
||||
destObj.enabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Extensions/DestructibleExtensions.cs.meta
vendored
Normal file
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Extensions/DestructibleExtensions.cs.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6eb3be1ee0fb46543b91b8fada9859a8
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
104
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Extensions/GameObjectExtensions.cs
vendored
Normal file
104
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Extensions/GameObjectExtensions.cs
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
// ReSharper disable ForCanBeConvertedToForeach
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
public static class GameObjectExtensions
|
||||
{
|
||||
/// <summary>Removes all components of type T from the game object and its children.</summary>
|
||||
public static void RemoveAllFromChildren<T>(this GameObject obj) where T : Component
|
||||
{
|
||||
if (obj == null) return;
|
||||
foreach (T comp in obj.GetComponentsInChildren<T>())
|
||||
Object.Destroy(comp);
|
||||
}
|
||||
|
||||
public static void RemoveComponent<T>(this GameObject obj) where T : Component
|
||||
{
|
||||
if (obj == null) return;
|
||||
T component = obj.GetComponent<T>();
|
||||
|
||||
if (component != null)
|
||||
Object.Destroy(component);
|
||||
}
|
||||
|
||||
public static List<T> GetComponentsInChildrenOnly<T>(this GameObject obj) where T : Component
|
||||
{
|
||||
return GetComponentsInChildrenOnly<T>(obj, false);
|
||||
}
|
||||
|
||||
public static List<T> GetComponentsInChildrenOnly<T>(this GameObject obj, bool includeInactive) where T : Component
|
||||
{
|
||||
var components = obj.GetComponentsInChildren<T>(includeInactive).ToList();
|
||||
components.Remove(obj.GetComponent<T>());
|
||||
return components;
|
||||
}
|
||||
|
||||
/// <summary>Be sure to set SolverIterationCount to around 25-30 in your Project Settings in order to get solid joints.</summary>
|
||||
public static void AddStiffJoint(this GameObject go, Rigidbody connectedBody, Vector3 anchorPosition, Vector3 axis, float breakForce, float breakTorque)
|
||||
{
|
||||
FixedJoint joint = go.AddComponent<FixedJoint>();
|
||||
joint.anchor = anchorPosition;
|
||||
joint.connectedBody = connectedBody;
|
||||
joint.breakForce = breakForce;
|
||||
joint.breakTorque = breakTorque;
|
||||
}
|
||||
|
||||
/// <summary>Attempts to get the center point location of a game object's combined meshes.</summary>
|
||||
/// <example>If your gameobject has multiple meshes under it which together make up a car (wheels, body, etc), this function will attempt to find
|
||||
/// the centerpoint of the car, taking into account all of the child meshes.</example>
|
||||
/// <param name="go">The gameobject parent containing the meshes.</param>
|
||||
/// <param name="meshRenderers">Pass in the collection of mesh renderers on this game object (including children) to save on performance.</param>
|
||||
/// <returns>The centerpoint location of the gameobject's meshes.</returns>
|
||||
public static Vector3 GetMeshCenterPoint(this GameObject go, MeshRenderer[] meshRenderers = null)
|
||||
{
|
||||
// first, get all the mesh renderers on the game object and children if they are not provided
|
||||
if (meshRenderers == null)
|
||||
meshRenderers = go.GetComponentsInChildren<MeshRenderer>();
|
||||
|
||||
// if there are no mesh renderers, return a zero vector (the gameobject's pivot position).
|
||||
if (meshRenderers.Length == 0)
|
||||
return Vector3.zero;
|
||||
|
||||
// if any mesh renderer on this game object is marked as Static, return a zero vector (the gameobject's pivot position) instead
|
||||
// of trying to get the bounding boxes of static meshes.
|
||||
if (go.IsAnyMeshPartOfStaticBatch(meshRenderers))
|
||||
return Vector3.zero;
|
||||
|
||||
// if we made it this far, calculate the center point of the combined mesh bounds for the object and use that.
|
||||
Bounds combinedBounds = new Bounds();
|
||||
|
||||
MeshFilter[] meshFilters = go.GetComponentsInChildren<MeshFilter>();
|
||||
foreach (MeshFilter meshFilter in meshFilters)
|
||||
{
|
||||
Mesh sharedMesh = meshFilter.sharedMesh;
|
||||
if (sharedMesh != null) // some meshFilters do not have shared meshes.
|
||||
combinedBounds.Encapsulate(sharedMesh.bounds);
|
||||
}
|
||||
|
||||
return combinedBounds.center;
|
||||
}
|
||||
|
||||
public static bool IsAnyMeshPartOfStaticBatch(this GameObject go, MeshRenderer[] meshRenderers = null)
|
||||
{
|
||||
// first, get all the mesh renderers on the game object and children if they are not provided
|
||||
if (meshRenderers == null)
|
||||
meshRenderers = go.GetComponentsInChildren<MeshRenderer>();
|
||||
|
||||
// if there are no mesh renderers, return false.
|
||||
if (meshRenderers.Length == 0)
|
||||
return false;
|
||||
|
||||
// if any mesh renderer on this game object is marked as Static, return true.
|
||||
for (int i = 0; i < meshRenderers.Length; i++)
|
||||
{
|
||||
if (meshRenderers[i].isPartOfStaticBatch)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Extensions/GameObjectExtensions.cs.meta
vendored
Normal file
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Extensions/GameObjectExtensions.cs.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 505d79f55b31a5848a3507d798740d6e
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
32
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Extensions/GizmoExtensions.cs
vendored
Normal file
32
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Extensions/GizmoExtensions.cs
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
public static class GizmoExtensions
|
||||
{
|
||||
/// <summary>Creates an editor-visible Gizmo for each damage effect, showing where they will play.</summary>
|
||||
public static void DrawGizmos(this List<DamageEffect> damageEffects, Transform transform)
|
||||
{
|
||||
if (damageEffects == null) return;
|
||||
|
||||
foreach (DamageEffect effect in damageEffects)
|
||||
{
|
||||
if (effect == null) continue;
|
||||
Gizmos.color = Color.cyan;
|
||||
Gizmos.DrawWireCube(transform.TransformPoint(effect.Offset), new Vector3(0.1f, 0.1f, 0.1f));
|
||||
Quaternion rotatedVector = transform.rotation * Quaternion.Euler(effect.Rotation);
|
||||
Gizmos.DrawRay(transform.TransformPoint(effect.Offset), rotatedVector * Vector3.forward * .5f);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Creates an editor-visible Gizmo for each CenterPointOverride for a Fallback Particle Effect.</summary>
|
||||
public static void DrawGizmos(this Vector3 centerPointOverride, Transform transform)
|
||||
{
|
||||
if (centerPointOverride == Vector3.zero) return;
|
||||
|
||||
Gizmos.color = Color.magenta;
|
||||
Gizmos.DrawWireSphere(transform.TransformPoint(centerPointOverride), 0.1f);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Extensions/GizmoExtensions.cs.meta
vendored
Normal file
11
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Extensions/GizmoExtensions.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a101a46a2c7abef4687612a2c307fe1e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
14
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Extensions/MaterialExtensions.cs
vendored
Normal file
14
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Extensions/MaterialExtensions.cs
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
public static class MaterialExtensions
|
||||
{
|
||||
public static bool IsProgressiveDamageCapable(this Material mat)
|
||||
{
|
||||
if (mat == null || mat.shader == null) return false;
|
||||
return mat.HasProperty("_DetailMask") && mat.HasProperty("_DetailAlbedoMap") && mat.HasProperty("_DetailNormalMap") && mat.GetTexture("_DetailMask") != null &&
|
||||
mat.GetTexture("_DetailAlbedoMap") != null && mat.GetTexture("_DetailNormalMap") != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Extensions/MaterialExtensions.cs.meta
vendored
Normal file
11
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Extensions/MaterialExtensions.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ae764e00d679d804f83eb97fa3b46897
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
23
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Extensions/StringExtensions.cs
vendored
Normal file
23
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Extensions/StringExtensions.cs
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
public static class StringExtensions
|
||||
{
|
||||
public static string SceneFolder(this string scenePath)
|
||||
{
|
||||
string[] pathParts = scenePath.Split('/');
|
||||
|
||||
if (pathParts.Length > 1)
|
||||
{
|
||||
string[] folderPath = new string[pathParts.Length - 1];
|
||||
|
||||
for (int i = 0; i < pathParts.Length - 1; i++)
|
||||
folderPath[i] = pathParts[i];
|
||||
return String.Join("/", folderPath);
|
||||
}
|
||||
|
||||
return scenePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Extensions/StringExtensions.cs.meta
vendored
Normal file
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Extensions/StringExtensions.cs.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 19de84c49e9991e45a5f29da0dffe76b
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
86
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Extensions/TagItExtensions.cs
vendored
Normal file
86
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Extensions/TagItExtensions.cs
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
// ReSharper disable ForCanBeConvertedToForeach
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
/// <summary>These extension methods work with the TagIt multi-tag system to make it easier to search for and add tags.</summary>
|
||||
public static class TagItExtensions
|
||||
{
|
||||
public static bool HasTag(this GameObject go, params Tag[] searchTags)
|
||||
{
|
||||
TagIt tagIt = go.GetComponent<TagIt>();
|
||||
if (tagIt == null) return false;
|
||||
|
||||
for (int i = 0; i < searchTags.Length; i++)
|
||||
{
|
||||
for (int j = 0; j < tagIt.tags.Count; j++)
|
||||
if (searchTags[i] == tagIt.tags[j])
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool HasTagInParent(this GameObject go, params Tag[] searchTags)
|
||||
{
|
||||
TagIt tagIt = go.GetComponentInParent<TagIt>();
|
||||
if (tagIt == null) return false;
|
||||
|
||||
for (int i = 0; i < searchTags.Length; i++)
|
||||
{
|
||||
for (int j = 0; j < tagIt.tags.Count; j++)
|
||||
if (searchTags[i] == tagIt.tags[j])
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void AddTag(this GameObject go, Tag tag)
|
||||
{
|
||||
TagIt tagIt = go.GetComponent<TagIt>();
|
||||
if (tagIt == null)
|
||||
{
|
||||
tagIt = go.AddComponent<TagIt>();
|
||||
tagIt.tags = new List<Tag>();
|
||||
}
|
||||
else if (tagIt.tags.Contains(tag))
|
||||
return;
|
||||
|
||||
tagIt.tags.Add(tag);
|
||||
}
|
||||
|
||||
public static void RemoveTag(this GameObject go, Tag tag)
|
||||
{
|
||||
TagIt tagIt = go.GetComponent<TagIt>();
|
||||
if (tagIt == null) return;
|
||||
|
||||
tagIt.tags.Remove(tag);
|
||||
}
|
||||
|
||||
/// <summary>Search for the highest parent found containing this tag.</summary>
|
||||
public static GameObject GetHighestParentWithTag(this GameObject go, Tag tag)
|
||||
{
|
||||
// First, get all parents of this gameobject.
|
||||
List<Transform> parents = new List<Transform>();
|
||||
Transform trans = go.transform;
|
||||
while (trans != null)
|
||||
{
|
||||
parents.Add(trans);
|
||||
trans = trans.parent;
|
||||
}
|
||||
|
||||
// Now check each parent, starting with the oldest one, to see if any contains the Tag.
|
||||
TagIt tagIt = null;
|
||||
for (int i = parents.Count - 1; i >= 0; i--)
|
||||
{
|
||||
tagIt = parents[i].GetComponent<TagIt>();
|
||||
if (tagIt != null && tagIt.tags.Contains(tag))
|
||||
return parents[i].gameObject;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Extensions/TagItExtensions.cs.meta
vendored
Normal file
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Extensions/TagItExtensions.cs.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bd49149637e7d974cbdf94df71dca769
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
44
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Extensions/TerrainExtensions.cs
vendored
Normal file
44
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Extensions/TerrainExtensions.cs
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
using UnityEngine;
|
||||
// ReSharper disable SuggestVarOrType_Elsewhere
|
||||
// ReSharper disable SuggestVarOrType_SimpleTypes
|
||||
// ReSharper disable ForCanBeConvertedToForeach
|
||||
// ReSharper disable SuggestVarOrType_BuiltInTypes
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
public static class TerrainExtensions
|
||||
{
|
||||
public static TerrainTree ClosestTreeToPoint(this Terrain terrain, Vector3 point)
|
||||
{
|
||||
TreeInstance[] trees = terrain.terrainData.treeInstances;
|
||||
if (trees.Length == 0) return null;
|
||||
|
||||
TerrainTree closestTree = new TerrainTree {Index = -1};
|
||||
float closestTreeDist = float.MaxValue;
|
||||
|
||||
for (int i = 0; i < trees.Length; i++)
|
||||
{
|
||||
Vector3 treePos = Vector3.Scale(trees[i].position, terrain.terrainData.size) + terrain.transform.position;
|
||||
float treeDist = Vector3.Distance(treePos, point);
|
||||
|
||||
if (treeDist < closestTreeDist)
|
||||
{
|
||||
closestTreeDist = treeDist;
|
||||
closestTree.Index = i;
|
||||
closestTree.Position = treePos;
|
||||
closestTree.TreeInstance = trees[i];
|
||||
}
|
||||
}
|
||||
|
||||
return closestTree;
|
||||
}
|
||||
|
||||
public static Vector3 WorldPositionOfTree(this Terrain terrain, int treeIndex)
|
||||
{
|
||||
TreeInstance[] trees = terrain.terrainData.treeInstances;
|
||||
if (trees.Length == 0) return Vector3.zero;
|
||||
|
||||
return Vector3.Scale(trees[treeIndex].position, terrain.terrainData.size) + terrain.transform.position;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Extensions/TerrainExtensions.cs.meta
vendored
Normal file
11
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Extensions/TerrainExtensions.cs.meta
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 72d78a56f36fb95459686acf834c58fe
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
31
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Extensions/Vector3Extensions.cs
vendored
Normal file
31
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Extensions/Vector3Extensions.cs
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
public static class Vector3Extensions
|
||||
{
|
||||
public static Vector3 LerpByDistance(this Vector3 startPoint, Vector3 endPoint, float distance)
|
||||
{
|
||||
Vector3 point = distance * Vector3.Normalize(endPoint - startPoint) + startPoint;
|
||||
return point;
|
||||
}
|
||||
|
||||
public static Vector3 ClosestDirection(this Vector3 vector)
|
||||
{
|
||||
Vector3[] compass = new Vector3[]{Vector3.left, Vector3.right, Vector3.forward, Vector3.back, Vector3.up, Vector3.down};
|
||||
Vector3 closestDirection = Vector3.zero;
|
||||
float maxDot = -(Mathf.Infinity);
|
||||
|
||||
foreach (Vector3 direction in compass)
|
||||
{
|
||||
float dot = Vector3.Dot(vector, direction);
|
||||
if (dot > maxDot) {
|
||||
closestDirection = direction;
|
||||
maxDot = dot;
|
||||
}
|
||||
}
|
||||
|
||||
return closestDirection;
|
||||
}
|
||||
}
|
||||
}
|
||||
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Extensions/Vector3Extensions.cs.meta
vendored
Normal file
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Extensions/Vector3Extensions.cs.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c0d0a5f4fc450344babc3dcafcf802fd
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
17
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Framework.meta
vendored
Normal file
17
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Framework.meta
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 492ea43f3a3ba414088aab46361dcb4c
|
||||
labels:
|
||||
- Destruction
|
||||
- Destroy
|
||||
- Physics
|
||||
- DestroyIt
|
||||
- Damage
|
||||
- Fracturing
|
||||
- Demolition
|
||||
folderAsset: yes
|
||||
timeCreated: 1427397479
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
57
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Framework/Enums.cs
vendored
Normal file
57
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Framework/Enums.cs
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
namespace DestroyIt
|
||||
{
|
||||
public enum Tag
|
||||
{
|
||||
ClingingDebris = 0,
|
||||
ClingPoint = 7,
|
||||
Concrete = 1,
|
||||
Glass = 2,
|
||||
MaterialTransferred = 3,
|
||||
Metal = 4,
|
||||
Paper = 5,
|
||||
Wood = 6,
|
||||
Powered = 8,
|
||||
Pooled = 9,
|
||||
Untagged = 10,
|
||||
DestructibleGroup = 11,
|
||||
Rubber = 12,
|
||||
Stuffing = 13,
|
||||
Plastic = 14,
|
||||
TerrainTree = 15,
|
||||
SpeedTree = 16,
|
||||
DontDoDamage = 17
|
||||
}
|
||||
|
||||
[System.Flags]
|
||||
public enum HitBy
|
||||
{
|
||||
Bullet = (1 << 0),
|
||||
Cannonball = (1 << 1),
|
||||
Axe = (1 << 2)
|
||||
}
|
||||
|
||||
public enum FacingDirection
|
||||
{
|
||||
None,
|
||||
FollowedObject,
|
||||
FixedPosition
|
||||
}
|
||||
|
||||
public enum WeaponType
|
||||
{
|
||||
Cannonball = 0,
|
||||
Rocket = 1,
|
||||
Gun,
|
||||
Nuke,
|
||||
Melee,
|
||||
RepairWrench
|
||||
}
|
||||
|
||||
public enum DestructionType
|
||||
{
|
||||
//TODO: Possible future limited destruction types for things beyond specified camera distance:
|
||||
//None,
|
||||
//FiftyPercentDebris,
|
||||
ParticleEffect = 0
|
||||
}
|
||||
}
|
||||
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Framework/Enums.cs.meta
vendored
Normal file
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Framework/Enums.cs.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 889efda6cb6fc8a42a42ceffbcf5a8e0
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
14
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Framework/HitEffect.cs
vendored
Normal file
14
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Framework/HitEffect.cs
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
[Serializable]
|
||||
public class HitEffect
|
||||
{
|
||||
/// <summary>The type of weapon the object was hit by. (Bullet, Slashing, Cannonball, etc)</summary>
|
||||
public HitBy hitBy;
|
||||
/// <summary>The effect to play when hit by this type of weapon.</summary>
|
||||
public GameObject effect;
|
||||
}
|
||||
}
|
||||
12
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Framework/HitEffect.cs.meta
vendored
Normal file
12
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Framework/HitEffect.cs.meta
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3a4454c59e6c84d438c612c4b88f752b
|
||||
timeCreated: 1484712234
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Framework/Interfaces.cs
vendored
Normal file
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Framework/Interfaces.cs
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
public interface Damage
|
||||
{
|
||||
float DamageAmount { get; set; }
|
||||
}
|
||||
}
|
||||
12
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Framework/Interfaces.cs.meta
vendored
Normal file
12
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Framework/Interfaces.cs.meta
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ffe5da0c083ba12438bd0c18ac72c538
|
||||
timeCreated: 1469680742
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
145
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Framework/ObjectModels.cs
vendored
Normal file
145
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Framework/ObjectModels.cs
vendored
Normal file
@@ -0,0 +1,145 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
// ReSharper disable IdentifierTypo
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
[Serializable]
|
||||
public class DamageLevel
|
||||
{
|
||||
public float maxHitPoints;
|
||||
public float minHitPoints;
|
||||
public int healthPercent;
|
||||
public bool hasError;
|
||||
public int visibleDamageLevel;
|
||||
}
|
||||
|
||||
/// <summary>A particle effect that is triggered at a specified damage level.</summary>
|
||||
[Serializable]
|
||||
public class DamageEffect
|
||||
{
|
||||
public int TriggeredAt;
|
||||
public Vector3 Offset;
|
||||
public Vector3 Rotation;
|
||||
public Vector3 Scale = Vector3.one;
|
||||
[FormerlySerializedAs("Effect")]
|
||||
public GameObject Prefab;
|
||||
public GameObject GameObject;
|
||||
public bool HasStarted;
|
||||
public bool HasTagDependency;
|
||||
public Tag TagDependency;
|
||||
public bool UnparentOnDestroy = true;
|
||||
public bool StopEmittingOnDestroy;
|
||||
public ParticleSystem[] ParticleSystems { get; set; }
|
||||
}
|
||||
|
||||
public class Debris
|
||||
{
|
||||
public Rigidbody Rigidbody { get; set; }
|
||||
public GameObject GameObject { get; set; }
|
||||
public bool IsActive
|
||||
{
|
||||
get {return (Rigidbody != null && GameObject.activeSelf);}
|
||||
}
|
||||
|
||||
public void Disable()
|
||||
{
|
||||
if (Rigidbody != null)
|
||||
GameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
public class ExplosiveDamage : Damage
|
||||
{
|
||||
public float BlastForce { get; set; }
|
||||
public Vector3 Position { get; set; }
|
||||
public float Radius { get; set; }
|
||||
public float UpwardModifier { get; set; }
|
||||
public float DamageAmount { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>Contains information about the object that collided with a destructible object.</summary>
|
||||
public class ImpactDamage : Damage
|
||||
{
|
||||
/// <summary>The amount of damage done by the impact force.</summary>
|
||||
public float DamageAmount { get; set; }
|
||||
|
||||
/// <summary>A reference to the object that collided into the destructible object.</summary>
|
||||
public Rigidbody ImpactObject { get; set; }
|
||||
|
||||
public Vector3 ImpactObjectVelocityFrom { get; set; }
|
||||
|
||||
public Vector3 ImpactObjectVelocityTo
|
||||
{
|
||||
get { return ImpactObjectVelocityFrom * -1; }
|
||||
}
|
||||
|
||||
public float AdditionalForce { get; set; }
|
||||
|
||||
public Vector3 AdditionalForcePosition { get; set; }
|
||||
|
||||
public float AdditionalForceRadius { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>Direct damage without any impact or force.</summary>
|
||||
public class DirectDamage : Damage
|
||||
{
|
||||
public float DamageAmount { get; set; }
|
||||
}
|
||||
|
||||
public class ActiveParticle
|
||||
{
|
||||
public GameObject GameObject { get; set; }
|
||||
public float InstantiatedTime { get; set; }
|
||||
public int ParentId { get; set; }
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class DamageMaterial
|
||||
{
|
||||
public string name;
|
||||
public List<Material> damageMaterials;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class MaterialMapping
|
||||
{
|
||||
public Material SourceMaterial;
|
||||
public Material ReplacementMaterial;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class PoolEntry
|
||||
{
|
||||
public GameObject Prefab;
|
||||
public int Count;
|
||||
public bool OnlyPooled;
|
||||
}
|
||||
|
||||
public class TerrainTree
|
||||
{
|
||||
public int Index { get; set; }
|
||||
public Vector3 Position { get; set; }
|
||||
public TreeInstance TreeInstance { get; set; }
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class DestructibleTree
|
||||
{
|
||||
public int prototypeIndex;
|
||||
public GameObject Prefab;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class TreeReset
|
||||
{
|
||||
public int prototypeIndex;
|
||||
public Vector3 position;
|
||||
public DateTime resetTime;
|
||||
public Color color;
|
||||
public float heightScale;
|
||||
public float widthScale;
|
||||
}
|
||||
}
|
||||
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Framework/ObjectModels.cs.meta
vendored
Normal file
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Framework/ObjectModels.cs.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1e4ec7c7c4f9fa8439737c3485bc1579
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
17
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Helpers.meta
vendored
Normal file
17
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Helpers.meta
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 64292b655103a0944a21912eb2a065d4
|
||||
labels:
|
||||
- Destruction
|
||||
- Destroy
|
||||
- Physics
|
||||
- DestroyIt
|
||||
- Damage
|
||||
- Fracturing
|
||||
- Demolition
|
||||
folderAsset: yes
|
||||
timeCreated: 1427397479
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
34
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Helpers/Check.cs
vendored
Normal file
34
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Helpers/Check.cs
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
public static class Check
|
||||
{
|
||||
public static bool IsDefaultParticleAssigned()
|
||||
{
|
||||
if (DestructionManager.Instance == null) return false;
|
||||
|
||||
if (DestructionManager.Instance.defaultParticle == null)
|
||||
{
|
||||
Debug.LogError("DestructionManager: Default Particle is not assigned. You should assign a default particle effect for simple destructible objects.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool LayerExists(string layerName, bool logMessage)
|
||||
{
|
||||
if (DestructionManager.Instance == null) return false;
|
||||
|
||||
int layer = LayerMask.NameToLayer(layerName);
|
||||
if (layer == -1)
|
||||
{
|
||||
if (logMessage)
|
||||
Debug.LogWarning(String.Format("[DestroyIt Core] Layer \"{0}\" does not exist. Please add a layer named \"{0}\" to your project.", layerName));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Helpers/Check.cs.meta
vendored
Normal file
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Helpers/Check.cs.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 02b0ef77a73e92145b8cb5fdfd1888cb
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
121
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Helpers/DestructibleHelper.cs
vendored
Normal file
121
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Helpers/DestructibleHelper.cs
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
public static class DestructibleHelper
|
||||
{
|
||||
/// <summary>When a Destructible Object is DESTROYED, this script will attempt to find and transfer the appropriate damaged materials over to the new prefab.</summary>
|
||||
public static void TransferMaterials(Destructible oldObj, GameObject newObj)
|
||||
{
|
||||
if (oldObj == null) return;
|
||||
|
||||
Renderer[] oldMeshes = oldObj.GetComponentsInChildren<Renderer>();
|
||||
Renderer[] newMeshes = newObj.GetComponentsInChildren<Renderer>();
|
||||
|
||||
// If either object has no meshes, then there's nothing to transfer, so exit.
|
||||
if (oldMeshes.Length == 0 || newMeshes.Length == 0) return;
|
||||
|
||||
//TODO: Should this be removed? It has been commented out for a while.
|
||||
// If there are no specified materials to replace, then exit, because we will just use the materials already assigned on the destroyed prefab.
|
||||
//if (oldObj.replaceMaterials == null || oldObj.replaceMaterials.Count == 0) return;
|
||||
|
||||
// Get new materials for each destroyed mesh
|
||||
for (int i = 0; i < newMeshes.Length; i++)
|
||||
{
|
||||
if (newMeshes[i] is MeshRenderer || newMeshes[i] is SkinnedMeshRenderer)
|
||||
newMeshes[i].materials = GetNewMaterialsForDestroyedMesh(newMeshes[i], oldObj);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For SpeedTree trees, locks the Hue Variation by setting the override property _HueVariationPos.
|
||||
/// This way, destroyed trees won't change color as they fall and roll around.
|
||||
/// Note that _HueVariationPos is a custom property added by the DestroyItSpeedTree custom shader.
|
||||
/// </summary>
|
||||
public static void LockHueVariation(this GameObject go)
|
||||
{
|
||||
if (go == null) return;
|
||||
|
||||
Renderer[] meshes = go.GetComponentsInChildren<Renderer>();
|
||||
if (meshes.Length == 0) return;
|
||||
for (int i = 0; i < meshes.Length; i++)
|
||||
{
|
||||
for (int j = 0; j < meshes[i].materials.Length; j++)
|
||||
{
|
||||
Material mat = meshes[i].materials[j];
|
||||
if (mat.HasProperty("_HueVariationPos"))
|
||||
mat.SetVector("_HueVariationPos", go.transform.position);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Material[] GetNewMaterialsForDestroyedMesh(Renderer destMesh, Destructible destructibleObj)
|
||||
{
|
||||
if (destructibleObj == null) return null;
|
||||
|
||||
Material[] curMats = destMesh.sharedMaterials;
|
||||
Material[] newMats = new Material[curMats.Length];
|
||||
|
||||
// For each of the old materials, try to get the destroyed version.
|
||||
for (int i = 0; i < curMats.Length; i++)
|
||||
{
|
||||
Material currentMat = curMats[i];
|
||||
if (currentMat == null) continue;
|
||||
|
||||
// First, see if we need to replace the material with one defined on the Destructible script.
|
||||
MaterialMapping matMap = destructibleObj.replaceMaterials.Find(x => x.SourceMaterial == currentMat);
|
||||
newMats[i] = matMap == null ? currentMat : matMap.ReplacementMaterial;
|
||||
|
||||
// If we are using Progressive Damage, try to get a destroyed version of the material.
|
||||
if (!destructibleObj.UseProgressiveDamage) continue;
|
||||
if (destructibleObj.damageLevels == null || destructibleObj.damageLevels.Count == 0)
|
||||
destructibleObj.damageLevels = DefaultDamageLevels();
|
||||
|
||||
DestructionManager.Instance.SetProgressiveDamageTexture(destMesh, newMats[i], destructibleObj.damageLevels[destructibleObj.damageLevels.Count - 1]);
|
||||
}
|
||||
return newMats;
|
||||
}
|
||||
|
||||
/// <summary>Reapply force to the impact object (if any) so it punches through the destroyed object.</summary>
|
||||
public static void ReapplyImpactForce(ImpactDamage info, float velocityReduction)
|
||||
{
|
||||
if (info.ImpactObject == null || info.ImpactObject.isKinematic) return;
|
||||
|
||||
info.ImpactObject.velocity = Vector3.zero; //zero out the velocity
|
||||
info.ImpactObject.AddForce(info.ImpactObjectVelocityTo * velocityReduction, ForceMode.Impulse);
|
||||
}
|
||||
|
||||
public static List<DamageLevel> DefaultDamageLevels()
|
||||
{
|
||||
// Initialize with default damage levels if null.
|
||||
return new List<DamageLevel>
|
||||
{
|
||||
new DamageLevel{healthPercent = 100, visibleDamageLevel = 0},
|
||||
new DamageLevel{healthPercent = 80, visibleDamageLevel = 2},
|
||||
new DamageLevel{healthPercent = 60, visibleDamageLevel = 4},
|
||||
new DamageLevel{healthPercent = 40, visibleDamageLevel = 6},
|
||||
new DamageLevel{healthPercent = 20, visibleDamageLevel = 8}
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>Removes colliders from the object and lets it fall through the terrain.</summary>
|
||||
public static void SinkAndDestroy(Destructible destObj)
|
||||
{
|
||||
// First, turn Kinematic off for all rigidbodies under this object.
|
||||
Rigidbody[] rbodies = destObj.GetComponentsInChildren<Rigidbody>();
|
||||
foreach (Rigidbody rbody in rbodies)
|
||||
{
|
||||
rbody.isKinematic = false;
|
||||
rbody.WakeUp();
|
||||
}
|
||||
// Next, strip off all colliders so it falls through the terrain.
|
||||
Collider[] colliders = destObj.GetComponentsInChildren<Collider>();
|
||||
foreach (Collider coll in colliders)
|
||||
coll.enabled = false;
|
||||
// Attach the DestroyAfter script to the object so it will get removed from the game.
|
||||
DestroyAfter destAfter = destObj.gameObject.AddComponent<DestroyAfter>();
|
||||
destAfter.seconds = 5f;
|
||||
}
|
||||
}
|
||||
}
|
||||
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Helpers/DestructibleHelper.cs.meta
vendored
Normal file
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Helpers/DestructibleHelper.cs.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a31acc56e013afd44b356df989ac3843
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
60
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Helpers/ExplosionHelper.cs
vendored
Normal file
60
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Helpers/ExplosionHelper.cs
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace DestroyIt
|
||||
{
|
||||
public static class ExplosionHelper
|
||||
{
|
||||
//TODO: IsExposedToBlast method is not used right now. Need to determine if it's worth fixing, and if so, how to fix it.
|
||||
//TODO: It was not reporting objects being exposed to blasts when at steep angles to, or in contact with, the object.
|
||||
/// <summary>Determines whether a collider object was exposed to a blast, by raycasting.</summary>
|
||||
/// <param name="gameObj">The game object that may be exposed to the blast.</param>
|
||||
/// <param name="explosion">The details about the blast.</param>
|
||||
public static bool IsExposedToBlast(this GameObject gameObj, ExplosiveDamage explosion)
|
||||
{
|
||||
RaycastHit hit;
|
||||
if (Physics.Raycast(explosion.Position, (gameObj.transform.position - explosion.Position), out hit, explosion.Radius))
|
||||
{
|
||||
Collider[] colliders = gameObj.GetComponentsInChildren<Collider>();
|
||||
foreach (Collider coll in colliders)
|
||||
{
|
||||
if (hit.collider == coll)
|
||||
{
|
||||
//Debug.DrawRay(explosion.Position, gameObj.transform.position - explosion.Position, Color.red, 5f);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
//Debug.DrawRay(explosion.Position, gameObj.transform.position - explosion.Position, Color.gray, 5f);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>Applies impact/explosive force to debris and collider for a realistic effect.</summary>
|
||||
/// <remarks>Force/Impact is reduced by the destroyed object's VelocityReduction amount (from XML config file).</remarks>
|
||||
public static void ApplyForcesToDebris<T>(GameObject destroyedObj, float velocityReduction, T damageInfo)
|
||||
{
|
||||
if (destroyedObj == null) { return; }
|
||||
|
||||
Rigidbody[] debrisRigidbodies = destroyedObj.GetComponentsInChildren<Rigidbody>();
|
||||
|
||||
// For Explosive Damage: Apply force to exposed debris from direction explosion originated, modified by proximity to the blast.
|
||||
if (damageInfo.GetType() == typeof(ExplosiveDamage))
|
||||
{
|
||||
ExplosiveDamage explosion = damageInfo as ExplosiveDamage;
|
||||
|
||||
// Apply explosive force to each debris piece. (NOTE: decided not to check if each piece of debris was exposed to the blast, because that effect was inaccurate when raycasting from steep angles.)
|
||||
foreach (Rigidbody debrisRigidbody in debrisRigidbodies)
|
||||
debrisRigidbody.AddExplosionForce(explosion.BlastForce, explosion.Position, explosion.Radius, explosion.UpwardModifier);
|
||||
}
|
||||
|
||||
if (damageInfo.GetType() == typeof(ImpactDamage))
|
||||
{
|
||||
ImpactDamage impact = damageInfo as ImpactDamage;
|
||||
if (impact != null && impact.AdditionalForce > 0f)
|
||||
{
|
||||
foreach (Rigidbody debrisRigidbody in debrisRigidbodies)
|
||||
debrisRigidbody.AddExplosionForce(impact.AdditionalForce, impact.AdditionalForcePosition, impact.AdditionalForceRadius, 0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Helpers/ExplosionHelper.cs.meta
vendored
Normal file
8
Assets/ThirdParty/DestroyIt/Scripts/Runtime/Helpers/ExplosionHelper.cs.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 191756bea7ece5942aae5305428a89c9
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user