# Path finding

In automation systems, material flow strategies are often very important for throughput and very often simulation models are created to develop and optimize these strategies. Our library is open and extensible and you can implement your own strategies.

### Basics

#### No successor or only one successor

[MUs](https://doc.realvirtual.io/components-and-scripts/mu-movable-unit) automatically enter the next path if the end of the current path is connected to another path. If no path is connected, the [MU](https://doc.realvirtual.io/components-and-scripts/mu-movable-unit) will normally stop at the end of the current (unconnected) path. If the *Exit Path* property of the [path mover](https://doc.realvirtual.io/extensions/page-4/path-system/pathmover) is set to *true*, the [MUs](https://doc.realvirtual.io/components-and-scripts/mu-movable-unit) will exit the path and be automatically controlled by physics.

#### More than one successor

If there is more than one successor for a path, the *TryMoveNext* public method is called in the [Path Mover](https://doc.realvirtual.io/extensions/page-4/path-system/pathmover). The following sequence of strategies is invoked:

**Step 1: Check the SelectNextPath methods of the components on the Path Mover**.

* First, all components on the [Path Mover](https://doc.realvirtual.io/extensions/page-4/path-system/pathmover) that implement the *ISelectNextPath* interface are selected. In all components, the *SelectNextPath* method is called with a reference to a list (in the Path Mover) of all successor paths.
* The implemented method *SelectNextPath* is able to remove paths from the list (so that this path is not taken as the next successor for sure) or to reorder the list so that a certain path is at the first position in the list.

\*\* Step 2: Checking the PathStratey referenced by Path\*\*.

* The next step is to check if the path has an assigned PathStrategy. If not, we proceed to step 3. The PathStrategy is a reference to a component that inherits from PathStrategy. In a PathStrategy, the public method *SelectNextPath* must be implemented.

\*\* Step 3: Check the SelectNextPath methods of components on the path itself\*\*.

* Next, call all components on the path itself that implement the *ISelectNextPath* interface. You will get the remaining list of successors from step2 (or a complete list of successors if no logic was found in step1)

\*\* Step 4: Select remaining path and move MU to next path\*\*.

* Now the remaining list of NextPaths is taken. If there is no content left because the strategies have removed all successor paths, nothing happens. Otherwise, the first path in the list is taken and the [MU](https://doc.realvirtual.io/components-and-scripts/mu-movable-unit) is moved to the next path.

\
This pictures shows the overall logic of path finding:

<figure><img src="https://260262196-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FpYxFg97YnJX96UzNNTSd%2Fuploads%2Fgit-blob-97dafb45d895899967b32c4847e293cd16ef89ec%2Fpath-strategy.png?alt=media" alt=""><figcaption></figcaption></figure>

### Implement your own strategies <a href="#implement-your-own-strategies" id="implement-your-own-strategies"></a>

You can implement your own strategies for selecting the next path. The only thing you need to do is to create a script that implements the interface *ISelectNextPath*.

{% hint style="info" %}
If you delete all [path movers](https://doc.realvirtual.io/extensions/page-4/path-system/pathmover) from the *NextPaths* list in your logic, the [path mover](https://doc.realvirtual.io/extensions/page-4/path-system/pathmover) will stop at the end of the current path. As soon as something changes in your system that could make the path strategy successful, you need to call *TryMoveNext* in the blocked [Path Mover](https://doc.realvirtual.io/extensions/page-4/path-system/pathmover). You can see this in the example in Option2 below.
{% endhint %}

#### Option1 - Add a component with the *ISelectNextPath* interface to a [Path Mover](https://doc.realvirtual.io/extensions/page-4/path-system/pathmover) or path.

Here is an example from the DemoPathsystem\_UseCases demonstration model. The *StrategyRandom* randomly selects the next path. It is attached as a component to the [Line](https://doc.realvirtual.io/extensions/page-4/path-system/line):

<div align="left"><figure><img src="https://260262196-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FpYxFg97YnJX96UzNNTSd%2Fuploads%2Fgit-blob-e8a62d10935d9f0a52f1e9662fe14e36185f6e54%2Fline-strategyrandom.png?alt=media" alt=""><figcaption></figcaption></figure></div>

The strategy itself looks like this:

```csharp
public class StrategyRandom : realvirtual.ioBehavior,ISelectNextPath
  {
      public int Seed = 1;
      
      public void SelectNextPath(PathMover pathMover,ref List<SimulationPath> Pathes)
      {
    
          var max = Pathes.Count-1;
          int random = (int)Mathf.Round(Random.Range(-0.4999f, max+0.4999f));
          var path = Pathes[random];
          Pathes.Remove(path);
          Pathes.Insert(0,path);
      }

      private void Start()
      {
          Random.seed = Seed;
      }
  }
```

#### Option2 - Add a reference to a component that inherits from PathStrategy. <a href="#option2-add-a-reference-to-a-component-that-inherits-from-pathstrategy" id="option2-add-a-reference-to-a-component-that-inherits-from-pathstrategy"></a>

Another way to define custom strategies is to reference a component in the path itself that inherits from PathStrategy. Here is an example of a strategy that limits the number in a given range.

The *SelectNextPath* method is called from the [Path Mover](https://doc.realvirtual.io/extensions/page-4/path-system/pathmover) located at the end of a path. If the current number in the range is greater than the allowed number, the list of paths is cleared. As a result, the [Path Mover](https://doc.realvirtual.io/extensions/page-4/path-system/pathmover) is stopped. The waiting [Path Mover](https://doc.realvirtual.io/extensions/page-4/path-system/pathmover) is added to the blocked list by calling *AddBlocked*.

During startup, event listeners are added on all paths entering or exiting the scope, referencing the *OnPathExit* or *OnPathEntered* methods. During simulation, these methods increment or decrement the counter. If the count is below the defined threshold, *AwakeBlocked* is called. *AwakeBlocked* is implemented in the PathStrategy base class. It calls *TryMoveNext* in all blocked [path movers](https://doc.realvirtual.io/extensions/page-4/path-system/pathmover).

```csharp
public class PathStrategyLimitNumber : PathStrategy
{
    [Header("Settings")]
    public int MaxNumber;

    [ReorderableList] public List<SimulationPath> AreaEnterPathes;
    [ReorderableList] public List<SimulationPath> AreaExitPathes;
    
    [Header("Status")]
    [realvirtual.io.ReadOnly] public int CurrentNumber;

    public override void SelectNextPath(PathMover pathMover,ref List<SimulationPath> pathes)
    {
        if (CurrentNumber >= MaxNumber)
        {
            AddBlocked(pathMover);
            pathes.Clear();
        }
    }

    public void OnPathEntered(SimulationPath path, PathMover pathMover)
    {
        CurrentNumber = CurrentNumber + 1;
    }
    
    public void OnPathExit(SimulationPath path, PathMover pathMover)
    {
        CurrentNumber = CurrentNumber - 1;
        if (CurrentNumber < MaxNumber)
            AwakeBlocked();
    }

    void Start()
    {
        CurrentNumber = 0;
        foreach (var enterpath in AreaEnterPathes)
        {
            enterpath.OnPathEntered.AddListener(OnPathEntered);
            foreach (var pred in enterpath.Predecessors)
            {
                pred.PathStrategy = this;
            }

        }
        foreach (var exitpath in AreaEnterPathes)
        {
            exitpath.OnPathExit.AddListener(OnPathExit);
        }
    }
}
```

© 2025 realvirtual GmbH [https://realvirtual.io](https://realvirtual.io/) - All rights reserved. No part of this publication may be reproduced, distributed, or transmitted in any form or by any means, including printing, saving, photocopying, recording, or other electronic or mechanical methods, without the prior written permission of the publisher.
