MagicaSphereCollider.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. // Magica Cloth.
  2. // Copyright (c) MagicaSoft, 2020-2022.
  3. // https://magicasoft.jp
  4. using UnityEngine;
  5. namespace MagicaCloth
  6. {
  7. /// <summary>
  8. /// 球コライダー
  9. /// </summary>
  10. [HelpURL("https://magicasoft.jp/magica-cloth-sphere-collider/")]
  11. [AddComponentMenu("MagicaCloth/MagicaSphereCollider")]
  12. public class MagicaSphereCollider : ColliderComponent
  13. {
  14. [SerializeField]
  15. [Range(0.001f, 0.5f)]
  16. private float radius = 0.05f;
  17. //=========================================================================================
  18. public override ComponentType GetComponentType()
  19. {
  20. return ComponentType.SphereCollider;
  21. }
  22. private void OnValidate()
  23. {
  24. if (Application.isPlaying)
  25. DataUpdate();
  26. }
  27. /// <summary>
  28. /// パーティクルのデータ更新処理
  29. /// </summary>
  30. internal override void DataUpdate()
  31. {
  32. base.DataUpdate();
  33. // radius, localPos
  34. foreach (var c in particleDict.Values)
  35. {
  36. for (int i = 0; i < c.dataLength; i++)
  37. {
  38. MagicaPhysicsManager.Instance.Particle.SetRadius(c.startIndex + i, radius);
  39. MagicaPhysicsManager.Instance.Particle.SetLocalPos(c.startIndex + i, Center);
  40. }
  41. }
  42. }
  43. //=========================================================================================
  44. public float Radius
  45. {
  46. get
  47. {
  48. return radius;
  49. }
  50. set
  51. {
  52. radius = value;
  53. ReserveDataUpdate();
  54. }
  55. }
  56. /// <summary>
  57. /// データハッシュ計算
  58. /// </summary>
  59. /// <returns></returns>
  60. public override int GetDataHash()
  61. {
  62. int hash = base.GetDataHash();
  63. hash += radius.GetDataHash();
  64. return hash;
  65. }
  66. protected override ChunkData CreateColliderParticleReal(int teamId)
  67. {
  68. uint flag = 0;
  69. flag |= PhysicsManagerParticleData.Flag_Kinematic;
  70. flag |= PhysicsManagerParticleData.Flag_Collider;
  71. flag |= PhysicsManagerParticleData.Flag_Transform_Read_Base;
  72. flag |= PhysicsManagerParticleData.Flag_Step_Update;
  73. flag |= PhysicsManagerParticleData.Flag_Reset_Position;
  74. flag |= PhysicsManagerParticleData.Flag_Transform_Read_Local;
  75. //flag |= PhysicsManagerParticleData.Flag_Transform_Read_Scl; // 現在スケールは見ていない
  76. var c = CreateParticle(
  77. flag,
  78. teamId, // team
  79. 0.0f, // depth
  80. radius,
  81. Center
  82. );
  83. if (c.IsValid())
  84. MagicaPhysicsManager.Instance.Team.AddCollider(teamId, c.startIndex);
  85. return c;
  86. }
  87. /// <summary>
  88. /// スケール値を取得
  89. /// </summary>
  90. /// <returns></returns>
  91. public float GetScale()
  92. {
  93. // X軸のみを見る
  94. return transform.lossyScale.x;
  95. }
  96. /// <summary>
  97. /// 指定座標に最も近い衝突点pと、中心軸からのpへの方向dirを返す。
  98. /// ※エディタ計算用
  99. /// </summary>
  100. /// <param name="pos"></param>
  101. /// <param name="p"></param>
  102. /// <param name="dir"></param>
  103. public override bool CalcNearPoint(Vector3 pos, out Vector3 p, out Vector3 dir, out Vector3 d, bool skinning)
  104. {
  105. dir = Vector3.zero;
  106. float scl = GetScale();
  107. //d = transform.position;
  108. d = transform.TransformPoint(Center);
  109. var v = pos - d;
  110. float vlen = v.magnitude;
  111. if (vlen <= Radius * scl)
  112. {
  113. // 衝突している
  114. p = pos;
  115. if (vlen > 0.0f)
  116. dir = v.normalized;
  117. }
  118. else
  119. {
  120. dir = v.normalized;
  121. p = d + dir * Radius;
  122. }
  123. return true;
  124. }
  125. }
  126. }