# Planetary Gravity: Usage & Setup Guide

#### What Planetary Gravity Does

Planetary gravity pulls the character **toward a gravity center point** instead of a fixed direction.

* Gravity direction is computed as (Center − CharacterLocation).GetSafeNormal()
* Updates during movement via `SetGravityDirFromState()`
* No surface normals are required
* Works on spheres, cylinders, or any radial gravity source
* Fully replicated and authority-safe
* Designed for walking on planets, asteroids, and rotating bodies
* High-Precision Support: Supports double-precision math (`FVector3d`) to ensure stability at large world distances.

***

### Required Setup

#### 1. Character Setup

Your character **must** use `UGravityMovementComponent`.

* Replace `CharacterMovementComponent` with `GravityMovementComponent`
* Replication must be enabled (default in constructor)
* Works with standard `ACharacter`

***

#### 2. Enable Planetary Gravity

Planetary gravity is enabled by setting the effective gravity mode and center:

```cpp
GravityMovementComponent->SetEffectiveGravityPlanetary(GravityCenter);
```

This **must** be called from a **server-replicated function**.

* Client calls are ignored
* Server computes gravity direction
* Resulting direction and rotation replicate to clients

***

### Gravity Center Rules

* Center is **world-space**
* Center represents the **point being pulled toward**
* Distance is irrelevant for direction (normalized internally)
* Invalid centers fall back to **Z-down**

#### Example

```cpp
// Planet centered at world origin
FVector(0, 0, 0);

// Planet centered at actor location
PlanetActor->GetActorLocation();
```

***

### Gravity Direction Calculation

Called during movement from `SetGravityDirFromState()`:

```cpp
const FVector ToCenter = GravityCenter - Character->GetActorLocation();
TargetDir = ToCenter.GetSafeNormal();
```

This vector is treated as DOWN.

* Always points inward toward center
* Smoothly updates as the character moves
* Stable across large radii
* At center singularity: maintains last cached direction

Special handling:

* `SurfaceGravityDirection` is updated to match `TargetDir` for lerp smoothing
* Singularity check prevents zero-vector at exact center
*

High-Precision Math:

* When `bUseHighPrecisionMath` is enabled, the calculation uses `FVector3d`. This treats the character as a temporary origin, eliminating "splitting" jitter and rounding errors at massive world coordinates.

***

### Rotation Behavior

#### Default Rotation

Character rotates so its down axis aligns with the radial direction.

* Rotation uses quaternion stepping when angle is large
* Uses lerp when close to target (within `RotationStopTolerance`)
* Max rotation per frame clamped by `RotationSpeed` \* `DeltaTime` (max 90°)
* Prevents sudden flips when crossing poles

#### Rotation Methods

Planetary mode uses two rotation methods based on alignment:

**Quaternion Rotation** (when NOT close to target):

* Angular stepping around computed axis
* Respects `GravityRotationMode` constraints
* Smooth transitions for large angle changes

**Lerp Smoothing** (when close to target):

* Interpolates toward `SurfaceGravityDirection`
* Speed controlled by `SurfaceLerpSpeed`
* Final alignment phase

***

#### Rotation Constraints (Optional)

Rotation can be constrained using the same modes as directional gravity:

```cpp
SetGravityRotationMode(EGravityRotationMode::Default);
SetGravityRotationMode(EGravityRotationMode::ForwardBack);
SetGravityRotationMode(EGravityRotationMode::LeftRight);
```

**Use Cases**

* Prevent roll on small planets
* Lock pitch while traversing equators
* Enforce gameplay-specific orientation rules

***

### Walking & Floor Detection

* Floor checks are performed **along the gravity direction**
* Walkable normals are evaluated relative to gravity
* Supports curved surfaces without custom traces
* No special collision setup required

***

### Moving / Rotating Planets

#### Important Limitation

Unreal does **not** replicate arbitrary base rotation for non-Z gravity.

This can cause:

* Client visual drift
* Z-down fallback on listen servers

#### Solution

If the planetary body is movable or rotating:

```cpp
bApplyReplicatedRotationOnMovingBases = true;
```

This:

* Tracks base quaternion deltas
* Applies gravity-aligned compensation
* Fixes visuals only (no physics side effects)

To completely ignore base rotation:

```cpp
bIgnoreBaseRotation = true;
```

***

### Flying Mode Interaction

#### Default

Planetary gravity does not rotate the character while flying.

* Early-out in `RotateCharacter()` when `MOVE_Flying` and `!bApplyGravityRotationWhileFlying`
* GravityDirCached is still updated (for other systems)
* No rotation applied

#### Optional

```cpp
bApplyGravityRotationWhileFlying = true;
```

Notes:

* Handled in `UpdateCharacterStateBeforeMovement()`
* Rotation remains radial
* Forward vector preserved during interpolation

### Networking & Replication

* `GravityMode` is replicated
* `GravityCenter` is replicated (`FVector_NetQuantize10`)
* `SurfaceGravityDirection` is replicated (`FVector_NetQuantizeNormal`)
* Gravity direction is computed from replicated center
* Rotation smoothing is client-predicted through `RotateCharacter()`
* Simulated proxies receive `ReplicatedComponentRotation` in `TickComponent()`
* Authority enforced on all gravity changes

***

### Blueprint Usage (Server-Authoritative)

#### Minimal Blueprint Flow

1. **From the Gravity Field or Gameplay Logic**
   * Detect overlap or trigger condition
2. **Call a&#x20;*****Server-Replicated*****&#x20;Function**
   * This function **must run on the server**
   * Gravity changes issued on clients are ignored
3. **Inside the Server Function**
   * Get:  `GravityMovementComponent`
   * Call: `SetEffectiveGravityPlanetary(GravityCenter)`
4. **Optional (Server Only)**
   * Set gravity rotation mode
   * Enable moving-base replication fixes

***

### Configuration Properties

#### Gravity Center

```cpp
GravityCenter  // World-space point (replicated as FVector_NetQuantize10)
bUseHighPrecisionMath // Enables double-precision calculations for large-scale stability.
```

#### Rotation Settings

```cpp
RotationSpeed           // Angular step speed for quaternion rotation
SurfaceLerpSpeed       // Lerp speed for final alignment
RotationStopTolerance  // Snap threshold angle
```

#### Surface Direction

```cpp
SurfaceGravityDirection  // Replicated target for lerp smoothing
```

#### Flying

```
bApplyGravityRotationWhileFlying  // Whether to align rotation to gravity while flying (default: false)
```

#### Moving Base

```
bApplyReplicatedRotationOnMovingBases  // Sync simulated proxy rotation on movable bases (default: false)
```

***

### Summary

* Planetary gravity uses radial pull toward a center point
* **v2.4.3 Feature**: High-precision math ensures stability at extreme world distances.
* Direction recalculated during movement from center and character position
* Rotation uses quaternion stepping and lerp smoothing
* Works on spheres and arbitrary radial bodies
* Singularity-safe at exact center
* Moving planets require opt-in base rotation replication
* Flying mode support is optional (disabled by default)
* Fully network-safe and scalable to object gravity


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://replicated-gravity.gitbook.io/replicated-gravity-docs/getting-started/setup-guides-and-tutorials/planetary-gravity-usage-and-setup-guide.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
