using UnityEngine; using System.Collections; using System.Collections.Generic; [RequireComponent(typeof(Rigidbody2D))] public class ContactDamage : MonoBehaviour { public float minImpulse = 100.0f; public float maxImpulse = 300.0f; public float maxDamage = 100.0f; private List _ignore = new List(); public void AddIgnoreObject(ContactDamage other) { _ignore.Add(other); } void FixedUpdate() { _ignore.Clear(); } void OnImpulse(float impulse, Vector2 point, GameObject impulseSource) { if (impulse >= minImpulse) { float k = 1.0f - (impulse - maxImpulse) / (minImpulse - maxImpulse); float damage = k * maxDamage; var health = GetComponent(); if (health != null) { health.ApplyDamage(damage, impulseSource, point); } } } void OnCollisionEnter2D(Collision2D col) { var otherHuman = col.transform.GetComponent(); var thisHuman = GetComponent(); if (otherHuman != null && thisHuman != null) { return; } var otherDamageController = col.transform.GetComponent(); if (otherDamageController != null){ if (_ignore.Contains(otherDamageController)) { Debug.Log("Skip damage on " + name); return; } else { otherDamageController.AddIgnoreObject(this); } } float impulse; var rb = GetComponent(); var v1 = rb.GetWorldPointVelocityEx(col.contacts[0].point); Vector2 v2 = Vector2.zero; float m2; Vector2 relativeVelocity; if (col.rigidbody != null && !col.rigidbody.isKinematic) { v2 = col.rigidbody.GetWorldPointVelocityEx(col.contacts[0].point); m2 = col.rigidbody.mass; } else { v2 = Vector2.zero; m2 = 0; } relativeVelocity = v2 - v1; impulse = (rb.mass*v1 + m2*v2).magnitude; Debug.LogFormat("Collision! Impulse = {0} on object {1} ({4}), relative velocity = {2}, self velocity = {3}", impulse, name, relativeVelocity.magnitude, v1.magnitude, col.transform.name); OnImpulse(impulse, col.contacts[0].point, col.gameObject); if (otherDamageController != null) { otherDamageController.OnImpulse(impulse, col.contacts[0].point, gameObject); } } }