1D Hopping Array Maze Inspired by We do tower hopping and related to 2D Maze Minus 1D
Introduction
Your task is to find the shortest path to get out of an array maze following specified rules.
Challenge
A 1D array a with n elements can be regarded as a maze composed of n points, where point with index k is connected to the points with k+a[k] and k-a[k] in a one-way manner. In other words, you can jump forward or backward exactly a[k] steps from the point with index k. Points with an index outside the bounds of the array are considered outside the maze.
To illustrate this, consider the following array,
[0,8,5,9,4,1,1,1,2,1,2]

If we are at the 5th element right now, since the element is 4, we can hop 4 steps forward to the 9th element, or 4 steps backward to the 1st element. If we do the latter, we end up with the element 0, which indicates no further moves are possible. If we do the former, since the 9th element is 2, we can choose to hop to the 11th element, which is again a 2, and then we can hop again to the &quot;13th element&quot;, which is out of the bounds of the array and considered an exit to the maze.
So if we start from the element in the middle, one way to get out of the maze is hopping 1 step back, 4 steps forward, 2 steps forward and again 2 steps forward, which can be expressed as the array [-1,4,2,2]. Alternatively you can express it with the array [4,8,10,12] which records the zero-based index of all intermediate and final points (1-based index is also fine), or just the signs, [-1,1,1,1].
Escaping the maze from the low-index end is also OK.
Using the first notation and starting from the same element, [1,1,1,2,2] is also a solution but it is not optimal since there are 5 steps instead of 4.
The task is to find out the shortest path to get out of the array maze and output the path. If there are more than one optimal paths, you can output any or all of them. If there are no solution, you should output a falsy value chosen by you that is discernible from a valid path (producing no output at all is also OK).
For simplicity, the number of elements in the array is always an odd number and we always start from the element in the middle.
Test cases
The test cases illustrates various forms of output, but you are not limited to these.
Input
Output

[0,8,5,9,4,1,1,1,2,1,2]
[-1,4,2,2]

[2,3,7,1,2,0,2,8,9]
[2,9] (or [2,-5] or [[2,9],[2,-5]])

[0,1,2,2,3,4,4,4,3,2,2,3,0]
[1,-1,1,1]

[0,1,2,2,4,4,6,6,6,6,6,4,2,1,2,2,0]
[]

Specs

You may write a function or a full program.

The array only contains nonnegative integers.

You can take input and output through any standard form, but please specify in your answer which form you are using.

This is code-golf, the lowest number of bytes wins.

As usual, default loopholes apply here.
JavaScript (ES6), 117 bytes
Returns an array of 0-indexed intermediate and final points, or an empty array if no solution exists.
a=&gt;(g=(x,p,d=a[x])=&gt;1/d?[d,-d].map(d=&gt;p.includes(X=x+d)||g(X,[...p,X])):o=o==''|o[p.length]?p:o)(a.length&gt;&gt;1,o=[])&amp;&amp;o

Try it online!
Commented
a =&gt;                              // given the maze a[]
  (g = (                          // g = recursive function taking:
    x,                            //   x = current position
    p,                            //   p[] = list of visited cells
    d = a[x]                      //   d = value of current cell
  ) =&gt;                            //
    1 / d ?                       // if d is defined:
      [d, -d].map(d =&gt;            //   for d and -d:
        p.includes(X = x + d) ||  //     if the cell at X = x + d was not yet visited,
        g(X, [...p, X])           //     do a recursive call to g() at this position
      )                           //   end of map()
    :                             // else:
      o =                         //   update o:
        o == '' |                 //     if o was empty
        o[p.length] ?             //     or p is shorter than o:
          p                       //       set o to p
        :                         //     else:
          o                       //       let o unchanged
  )(a.length &gt;&gt; 1, o = [])        // initial call to g(), starting in the middle
  &amp;&amp; o                            // return o