How to Create a Real-Time Physics Attractor and Custom Gravity in Unity C#
26 Aug 26 (2mo ago)
Building physics-driven interactions where objects follow a moving target in real-time is a common mechanic in games, useful for item collection, orbital mechanics, magnetic forces, or interactive particle spheres.
Implementing this effectively requires syncing with Unity's physics step, preventing aggressive orbiting, and adjusting gravity per object when the default $-9.81\text{ m/s}^2$ downward pull is too heavy.
1. Implementing the Target Attractor Script
When manipulating physics objects (Rigidbody), always apply forces inside FixedUpdate rather than Update to avoid jitter and unpredictable behavior across varying frame rates.
The Full Attractor Script
using UnityEngine;
public class AttractorCon : MonoBehaviour
{
[Header("Targets")]
public GameObject[] emojiBalls;
[Header("Attraction Settings")]
public float attractionStrength = 5f; // Strength of the pull
public float damping = 0.5f; // Dampens velocity to prevent endless orbiting
[Header("Custom Gravity")]
public bool useCustomGravity = true;
public float customGravityY = -2f; // Custom gravity acceleration (e.g., -2 instead of -9.81)
void FixedUpdate()
{
Vector3 targetPosition = transform.position;
foreach (GameObject ball in emojiBalls)
{
if (ball != null && ball.TryGetComponent<Rigidbody>(out Rigidbody rb))
{
// Apply custom gravity per object if enabled
if (useCustomGravity)
{
rb.useGravity = false;
Vector3 customGravity = new Vector3(0f, customGravityY, 0f);
rb.AddForce(customGravity, ForceMode.Acceleration);
}
// 1. Calculate direction vector from object to attractor
Vector3 direction = targetPosition - ball.transform.position;
float distance = direction.magnitude;
// 2. Scale force by distance for an elastic spring effect
Vector3 attractionForce = direction.normalized * distance * attractionStrength;
// 3. Apply force with velocity damping to stabilize motion
rb.AddForce(attractionForce - (rb.velocity * damping));
}
}
}
}
2. Core Mechanics Breakdown
- Distance-Based Acceleration: Multiplying the normalized direction by
distance * attractionStrengthcreates a spring-like force that pulls distant objects faster while easing them in as they approach. - Velocity Damping: Subtracting
rb.velocity * dampingcounteracts continuous angular velocity, preventing objects from infinitely orbiting around the attractor origin. TryGetComponentSafety: Eliminates runtime null reference exceptions if an array element lacks aRigidbodycomponent.
3. How to Set Custom Gravity in Unity
Unity's built-in useGravity toggle only switches between $0\text{ m/s}^2$ and the global physics gravity (default $-9.81\text{ m/s}^2$). When you need a specific low-gravity value like $-2\text{ m/s}^2$:
Option A: Global Scene Gravity
- Open Edit > Project Settings.
- Navigate to Physics in the left sidebar.
- Under Gravity, update the Y field from
-9.81to-2.
Use this when all physics entities across the entire scene require the same floaty behavior.
Option B: Per-Object Scripted Force
- Uncheck
Use Gravityon the target object'sRigidbody. - Apply
rb.AddForce(new Vector3(0f, -2f, 0f), ForceMode.Acceleration)withinFixedUpdate.
Use this when only selected objects should fall slowly while standard environment objects retain full earth gravity.