MegaHitDeform.cs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. using UnityEngine;
  2. [AddComponentMenu("Modifiers/Hit")]
  3. public class MegaHitDeform : MegaModifier
  4. {
  5. public override string ModName() { return "Hit Deform"; }
  6. public float hitradius = 1.0f;
  7. public float Hardness = 0.5f;
  8. public float deformlimit = 0.1f;
  9. public float scaleforce = 1000.0f;
  10. public float maxForce = 1.0f;
  11. Vector3[] offsets;
  12. float msize;
  13. public override void Modify(MegaModifiers mc)
  14. {
  15. if ( offsets != null )
  16. {
  17. for ( int i = 0; i < sverts.Length; i++ )
  18. sverts[i] = verts[i] + offsets[i];
  19. }
  20. }
  21. public void Deform(Vector3 point, Vector3 normal, float force)
  22. {
  23. force = Mathf.Min(maxForce, force);
  24. if ( force > 0.01f )
  25. {
  26. float df = force * (msize * (0.1f / Mathf.Max(0.1f, Hardness)));
  27. float max = deformlimit;
  28. float maxsqr = max * max;
  29. Vector3 p = transform.InverseTransformPoint(point);
  30. Vector3 nr = transform.InverseTransformDirection(normal);
  31. for ( int i = 0; i < verts.Length; i++ )
  32. {
  33. float d = ((verts[i] + offsets[i]) - p).sqrMagnitude;
  34. if ( d <= df )
  35. {
  36. Vector3 n = nr * (1.0f - (d / df)) * df;
  37. offsets[i] += n;
  38. if ( deformlimit > 0.0f )
  39. {
  40. n = offsets[i];
  41. d = n.sqrMagnitude;
  42. if ( d > maxsqr )
  43. offsets[i] = (n * (max / n.magnitude));
  44. }
  45. }
  46. }
  47. }
  48. }
  49. void Deform(Collision collision)
  50. {
  51. #if UNITY_5 || UNITY_2017 || UNITY_2018 || UNITY_2019 || UNITY_2020
  52. float cf = Mathf.Min(maxForce, collision.relativeVelocity.sqrMagnitude / scaleforce);
  53. #else
  54. float cf = Mathf.Min(maxForce, collision.impactForceSum.sqrMagnitude / scaleforce);
  55. #endif
  56. if ( cf > 0.01f )
  57. {
  58. ContactPoint[] contacts = collision.contacts;
  59. for ( int c = 0; c < contacts.Length; c++ )
  60. Deform(contacts[c].point, contacts[c].normal, cf);
  61. }
  62. }
  63. public override bool ModLateUpdate(MegaModContext mc)
  64. {
  65. return Prepare(mc);
  66. }
  67. public override bool Prepare(MegaModContext mc)
  68. {
  69. if ( offsets == null || offsets.Length != mc.mod.verts.Length )
  70. offsets = new Vector3[mc.mod.verts.Length];
  71. msize = MegaUtils.SmallestValue(mc.bbox.Size());
  72. return true;
  73. }
  74. public void Repair(float repair)
  75. {
  76. Repair(repair, Vector3.zero, 0.0f);
  77. }
  78. public void Repair(float repair, Vector3 point, float radius)
  79. {
  80. point = transform.InverseTransformPoint(point);
  81. float rsqr = radius * radius;
  82. for ( int i = 0; i < offsets.Length; i++ )
  83. {
  84. if ( radius > 0.0f )
  85. {
  86. Vector3 vector3 = point - verts[i];
  87. if ( vector3.sqrMagnitude >= rsqr )
  88. break;
  89. }
  90. offsets[i] *= repair;
  91. }
  92. }
  93. public void OnCollisionEnter(Collision collision)
  94. {
  95. Deform(collision);
  96. }
  97. public void OnCollisionStay(Collision collision)
  98. {
  99. Deform(collision);
  100. }
  101. }