---
tags:
    - "Bounce"
    - "Yoyo"
    - "Back"
    - "Forth"
    - "Oscillate"
    - "Range"
---

# Ping Pong

[Math](../index.md) / [Range](index.md) / **Ping Pong**

<div class="grid cards" markdown>

* :green_circle: Can Read

* :red_circle: Cannot Write

</div>

## Description

Bounces a number back and forth between zero and a length

## Parameters

| Name | Description |
| :--- | :---------- |
| Number | The number that bounces |
| Length | The highest value the result reaches before going back down |

## Code

```cs
using System;
using UnityEngine;
using VisualScript.Icons;

namespace VisualScript.Runtime
{
    [Get]

    [Title("Ping Pong")]
    [Category("Math/Range/Ping Pong")]

    [Description("Bounces a number back and forth between zero and a length")]
    [Image(typeof(IconTravelingWave), ColorTheme.Type.Yellow)]

    [Parameter("Number", "The number that bounces")]
    [Parameter("Length", "The highest value the result reaches before going back down")]

    [Keywords("Bounce", "Yoyo", "Back", "Forth", "Oscillate", "Range")]

    [Serializable]
    public class TypeNumberMathPingPong : TypeNumber
    {
        [SerializeField] private GetNumber m_Number = new GetNumber();
        [SerializeField] private GetNumber m_Length = new GetNumber(1f);

        public override double GetPreview(GameObject source) => PingPong(
            this.m_Number.GetPreview(source),
            this.m_Length.GetPreview(source)
        );

        public override double Get(Args args) => PingPong(
            this.m_Number.Get(args),
            this.m_Length.Get(args)
        );

        private static double PingPong(double number, double length)
        {
            if (Math.Abs(length) <= double.Epsilon) return 0f;

            double cycle = length * 2f;
            double repeat = number - Math.Floor(number / cycle) * cycle;

            return length - Math.Abs(repeat - length);
        }

        public override string ToString()
        {
            return $"PingPong({this.m_Number}, {this.m_Length})";
        }

        protected override SubscriptionMode Subscription => SubscriptionMode.OnChange;
    }
}

```

