SanAndreasUnity/Assets/Scripts/Utilities/ExplosionForce.cs

68 lines
2.2 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace SanAndreasUnity.Utilities
{
public class ExplosionForce : MonoBehaviour
{
public float explosionForce = 4;
public float upwardsModifier = 1f;
public float radius = 10f;
public float explosionMultiplier = 1f;
public LayerMask layerMask;
private IEnumerator Start()
{
// wait one frame because some objects can be spawned right after the explosion
yield return null;
float multiplier = this.explosionMultiplier;
float r = radius * multiplier;
var cols = Physics.OverlapSphere(this.transform.position, r, layerMask);
var rigidbodies = new Dictionary<Rigidbody, List<Collider>>();
foreach (var col in cols)
{
if (col.attachedRigidbody != null)
{
if (rigidbodies.ContainsKey(col.attachedRigidbody))
{
rigidbodies[col.attachedRigidbody].Add(col);
}
else
{
rigidbodies.Add(col.attachedRigidbody, new List<Collider>() { col });
}
}
}
foreach (var pair in rigidbodies)
{
Rigidbody rb = pair.Key;
var colliders = pair.Value;
// apply higher force on objects with higher mass
float massFactor = Mathf.Pow(rb.mass, 0.95f);
foreach (var collider in colliders)
{
Vector3 closestPointOnCollider = collider.ClosestPointOrBoundsCenter(this.transform.position);
Vector3 diff = closestPointOnCollider - this.transform.position;
float distance = diff.magnitude;
float distanceFactor = Mathf.Sqrt(1.0f - Mathf.Clamp01(distance / r));
rb.AddForceAtPosition((diff.normalized * explosionForce + Vector3.up * upwardsModifier) * multiplier * distanceFactor * massFactor / colliders.Count, closestPointOnCollider, ForceMode.Impulse);
}
}
}
}
}