/// <summary> /// Calculates force over a <paramref name="distance"/> using <paramref name="falloffMode"/> /// </summary> public static float ProcessFalloff(float distance, ForceFalloffMode falloffMode) { switch (falloffMode) { case ForceFalloffMode.None: return(1); case ForceFalloffMode.Linear: return(1 / distance); case ForceFalloffMode.Squared: return(1 / Mathf.Sqrt(distance)); default: throw new System.NotImplementedException(); } }
/// <summary> /// Will add force from <paramref name="center"/> to all objects within <paramref name="radius"/> /// </summary> public static void AddForceAll(Vector2 center, float radius, float force, ForceMode2D forceMode = ForceMode2D.Force, ForceFalloffMode falloffMode = ForceFalloffMode.Linear, int layerMask = Physics2D.DefaultRaycastLayers) { int hitCount = Physics2D.CircleCastNonAlloc(center, radius, Vector2.zero, HitBuffer, 0, layerMask); for (int i = 0; i < hitCount; i++) { RaycastHit2D hit = HitBuffer[i]; Vector2 delta = (Vector2)hit.transform.position - center; if (delta.magnitude == 0) { continue; } Interactable interactable = hit.collider.GetComponent <Interactable>(); EntityController controller = interactable?.Entity?.EntityController; float falloff = ProcessFalloff(delta.magnitude, falloffMode); if (controller != null) { controller.AddForce(delta.normalized * force * falloff, forceMode); } else if (hit.rigidbody != null) { hit.rigidbody.AddForce(delta.normalized * force * falloff, forceMode); } } }