Class ScrollPhysics
Handles momentum decay and elastic bounce calculations for smooth scrolling. Provides iOS-style physics for pixel-based scroll views, including drag tracking, fling momentum, elastic over-scroll, and optional line snapping.
Inherited Members
Namespace: Scylla.Core.Util.UI
Assembly: ScyllaCore.dll
Syntax
public sealed class ScrollPhysics
Remarks
Thread Safety: This class is NOT thread-safe. All methods must be called from the Unity main thread.
Timing: All timing calculations use UnityEngine.Time.unscaledTime to ensure
scroll physics work correctly even when UnityEngine.Time.timeScale is modified
(for example, during pause).
Constructors
ScrollPhysics()
Creates a new ScrollPhysics instance with default settings.
Declaration
public ScrollPhysics()
Fields
DEFAULT_DECELERATION_RATE
Default deceleration rate for momentum scrolling. Matches iOS UIScrollView default (0.998 per frame at 60fps converted to per-second).
Declaration
public const float DEFAULT_DECELERATION_RATE = 0.135
Field Value
| Type | Description |
|---|---|
| float |
DEFAULT_ELASTIC_DURATION
Default duration for elastic bounce-back animation in seconds.
Declaration
public const float DEFAULT_ELASTIC_DURATION = 0.5
Field Value
| Type | Description |
|---|---|
| float |
DEFAULT_ELASTIC_STRENGTH
Default elastic strength factor. Lower values allow more overshoot.
Declaration
public const float DEFAULT_ELASTIC_STRENGTH = 0.3
Field Value
| Type | Description |
|---|---|
| float |
MAX_ELASTIC_OVERSHOOT
Maximum elastic overshoot distance in pixels.
Declaration
public const float MAX_ELASTIC_OVERSHOOT = 200
Field Value
| Type | Description |
|---|---|
| float |
VELOCITY_THRESHOLD
Minimum velocity threshold below which momentum stops.
Declaration
public const float VELOCITY_THRESHOLD = 1
Field Value
| Type | Description |
|---|---|
| float |
Properties
DecelerationRate
Gets or sets the deceleration rate for momentum scrolling. Higher values stop faster. Clamped to the range [0.01, 0.5].
Declaration
public float DecelerationRate { get; set; }
Property Value
| Type | Description |
|---|---|
| float | The deceleration rate, clamped to [0.01, 0.5].
The default value |
ElasticDuration
Gets or sets the elastic bounce-back duration in seconds.
Declaration
public float ElasticDuration { get; set; }
Property Value
| Type | Description |
|---|---|
| float |
ElasticStrength
Gets or sets the elastic strength factor. Higher values resist overshoot more. Range: 0.1 to 1.0.
Declaration
public float ElasticStrength { get; set; }
Property Value
| Type | Description |
|---|---|
| float |
EnableLineSnapping
Gets or sets whether line snapping is enabled. When true, scroll position snaps to line boundaries when scrolling stops.
Declaration
public bool EnableLineSnapping { get; set; }
Property Value
| Type | Description |
|---|---|
| bool |
IsDragging
Gets whether the user is currently dragging.
Declaration
public bool IsDragging { get; }
Property Value
| Type | Description |
|---|---|
| bool |
IsElasticBouncing
Gets whether elastic bounce animation is currently active.
Declaration
public bool IsElasticBouncing { get; }
Property Value
| Type | Description |
|---|---|
| bool |
IsMomentumActive
Gets whether momentum scrolling is currently active.
Returns true only when all three conditions hold: the absolute velocity exceeds
VELOCITY_THRESHOLD, no drag is in progress (_isDragging is false),
and no elastic bounce animation is running (_isElasticBouncing is false).
Declaration
public bool IsMomentumActive { get; }
Property Value
| Type | Description |
|---|---|
| bool |
IsScrolling
Gets whether any scrolling animation is currently active.
Returns true if at least one of these components is active:
IsMomentumActive (fling deceleration is in progress),
IsElasticBouncing (over-scroll bounce-back is in progress),
or the internal animated scroll flag _isAnimating (a programmatic
ScrollTo animation is in progress).
Declaration
public bool IsScrolling { get; }
Property Value
| Type | Description |
|---|---|
| bool |
LineHeight
Gets or sets the line height for line-snapping behavior. Set to 0 to disable line snapping.
Declaration
public float LineHeight { get; set; }
Property Value
| Type | Description |
|---|---|
| float |
MaxScrollPosition
Gets the maximum scroll position based on content height.
Declaration
public float MaxScrollPosition { get; }
Property Value
| Type | Description |
|---|---|
| float |
MinScrollPosition
Gets the minimum scroll position (usually 0).
Declaration
public float MinScrollPosition { get; }
Property Value
| Type | Description |
|---|---|
| float |
ScrollPosition
Gets the current scroll position in pixels, measured from the top of the content. A value of 0 means the view is scrolled to the very top of the content. Positive values indicate how far the content has been scrolled downward.
Declaration
public float ScrollPosition { get; }
Property Value
| Type | Description |
|---|---|
| float |
Velocity
Gets the current scroll velocity in pixels per second. Positive values move the scroll position downward (content scrolls up). Negative values move the scroll position upward (content scrolls down).
Declaration
public float Velocity { get; }
Property Value
| Type | Description |
|---|---|
| float |
Methods
ApplyScrollVelocity(float)
Applies an additional velocity impulse for momentum-based scrolling, such as a mouse wheel tick.
This method accumulates velocity by adding velocityDelta to the existing
velocity, allowing rapid wheel events to build up speed naturally.
Any active elastic bounce or programmatic animation is cancelled before adding velocity.
Declaration
public void ApplyScrollVelocity(float velocityDelta)
Parameters
| Type | Name | Description |
|---|---|---|
| float | velocityDelta | The velocity to add in pixels per second. Positive values scroll downward. |
EndDrag(float?, float)
Ends the drag operation, potentially starting momentum scrolling or an elastic bounce.
Declaration
public void EndDrag(float? finalPosition = null, float sensitivity = 1)
Parameters
| Type | Name | Description |
|---|---|---|
| float? | finalPosition | Optional final drag position. When provided, one last velocity sample is recorded before the drag ends to capture any last movement. |
| float | sensitivity | Sensitivity multiplier used during drag (default 1.0). |
Remarks
The release velocity is computed as a weighted average of the most recent velocity
samples. Samples are weighted by recency: a sample taken just before release
receives weight 1.0, while a sample taken VELOCITY_SAMPLE_MAX_AGE seconds
earlier receives weight 0.0. Samples older than VELOCITY_SAMPLE_MAX_AGE
(0.15 seconds) are discarded entirely and do not contribute to the result.
ScrollBy(float)
Scrolls by the specified number of pixels immediately, without animation. Any active momentum, elastic bounce, or animated scroll is cancelled first.
Declaration
public void ScrollBy(float pixels)
Parameters
| Type | Name | Description |
|---|---|---|
| float | pixels | The amount to scroll in pixels. Positive scrolls downward. |
Remarks
If line snapping is enabled (EnableLineSnapping is true) and
LineHeight is greater than zero, a deferred snap animation is scheduled.
The snap fires after IDLE_SNAP_DELAY (0.15 seconds) of no further scroll
input, rounding the final position to the nearest line boundary.
ScrollTo(float, bool, float)
Scrolls to the specified position, optionally with animation.
Declaration
public void ScrollTo(float position, bool animate = false, float duration = 0.3)
Parameters
| Type | Name | Description |
|---|---|---|
| float | position | The target scroll position in pixels. Clamped to
[ |
| bool | animate | When |
| float | duration | Animation duration in seconds. Only used when |
ScrollToBottom(bool)
Scrolls to the bottom (maximum position).
Declaration
public void ScrollToBottom(bool animate = false)
Parameters
| Type | Name | Description |
|---|---|---|
| bool | animate | Whether to animate the scroll. |
ScrollToTop(bool)
Scrolls to the top (position 0).
Declaration
public void ScrollToTop(bool animate = false)
Parameters
| Type | Name | Description |
|---|---|---|
| bool | animate | Whether to animate the scroll. |
SetBounds(float, float)
Sets the scroll bounds based on content and viewport sizes.
The minimum scroll position is always 0; the maximum is
max(0, contentHeight - viewportHeight).
Declaration
public void SetBounds(float contentHeight, float viewportHeight)
Parameters
| Type | Name | Description |
|---|---|---|
| float | contentHeight | Total content height in pixels. Negative values are treated as 0, resulting in a maximum scroll position of 0. |
| float | viewportHeight | Viewport height in pixels. Negative values are treated as 0. |
Remarks
The current scroll position is clamped to the new bounds, except when a drag, elastic bounce, or momentum over-scroll is active, in which case clamping is deferred so the interaction can complete naturally.
SetScrollPosition(float)
Sets the scroll position directly without animation. Cancels any active scrolling.
Declaration
public void SetScrollPosition(float position)
Parameters
| Type | Name | Description |
|---|---|---|
| float | position | The scroll position in pixels. |
StartDrag(float)
Starts a drag operation at the specified position. Cancels any active momentum, elastic bounce animation, or programmatic scroll animation before recording the drag start state.
Declaration
public void StartDrag(float position)
Parameters
| Type | Name | Description |
|---|---|---|
| float | position | The initial drag position in pixels. |
StopScrolling()
Stops all scrolling animations and momentum.
Declaration
public void StopScrolling()
Update(float)
Updates the physics simulation. Call this every frame.
Declaration
public bool Update(float deltaTime)
Parameters
| Type | Name | Description |
|---|---|---|
| float | deltaTime | Time since last update in seconds. |
Returns
| Type | Description |
|---|---|
| bool |
|
UpdateDrag(float, float)
Updates the drag with a new position.
Declaration
public void UpdateDrag(float position, float sensitivity = 1)
Parameters
| Type | Name | Description |
|---|---|---|
| float | position | The current drag position in pixels. |
| float | sensitivity | Optional multiplier applied to the drag delta. Values greater than 1.0 amplify movement so the content moves faster than the pointer; values less than 1.0 reduce movement so the content moves slower than the pointer. Defaults to 1.0 (1:1 tracking). |