83 lines
2.4 KiB
C#
83 lines
2.4 KiB
C#
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<ContactDamage> _ignore = new List<ContactDamage>();
|
||
|
|
|
||
|
|
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<Health>();
|
||
|
|
if (health != null) {
|
||
|
|
health.ApplyDamage(damage, impulseSource, point);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void OnCollisionEnter2D(Collision2D col) {
|
||
|
|
var otherHuman = col.transform.GetComponent<HumanController>();
|
||
|
|
var thisHuman = GetComponent<HumanController>();
|
||
|
|
if (otherHuman != null && thisHuman != null) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
var otherDamageController = col.transform.GetComponent<ContactDamage>();
|
||
|
|
if (otherDamageController != null){
|
||
|
|
if (_ignore.Contains(otherDamageController)) {
|
||
|
|
Debug.Log("Skip damage on " + name);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
otherDamageController.AddIgnoreObject(this);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
float impulse;
|
||
|
|
var rb = GetComponent<Rigidbody2D>();
|
||
|
|
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);
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|