Forum Discussion

AaronBurgessAU's avatar
AaronBurgessAU
Community Member
3 months ago
Solved

Is there a way to auto run some triggers in a loop until the results are met?

I have a project with 4 objects that need to appear randomly in 1 of 4 rows.

I've set up a test slide where I generate a number between 1 and 4. At the moment if A and B are the same number I have to click a button to open the trigger layer to generate a new number for B. With C, if it's number is the same as A or B I have to click a button to randomise that until I get a result that doesn't match either A or B. With D I still have to click a button, but it automatically takes the value that is not used by A, B, or C

This all works perfectly, but I am required to press a button to re-randomise each variable until it is no longer equal to another existing variable. Does anyone know of a way to basically run a loop test until the desired results are found?

This is in Storyline 360 to clarify.

  • JavaScript is more elegant and efficient, but for a few variables, you can do it with a handful of triggers on a layer.

    Demo: https://360.articulate.com/review/content/041f67c6-c44a-47e8-a301-632caa78772b/review

    This just shows a layer that assigns 4 random numbers to 4 variables. If any are the same, it reruns the the layer until they are all unique. This is very brute-force, but very simple. The triggers are fast enough that even if it takes many attempts, it is still practically instant.

    This could be modified with a few more triggers to be more elegant, recalculating each random number only if it matches one of the previous variables, but in the end it is essentially the same thing. Simple gets the job done.

    As Nedim mentioned, if you try this with many variables, it could begin to slow down, or require too many triggers. In that case, JavaScript is the way to go. 

7 Replies

  • Nedim's avatar
    Nedim
    Community Member

    You're running into a limitation: Storyline doesn’t support traditional loops or real-time conditional recursion, so using a button click to re-randomize each variable is about as close as you can get with built-in triggers and conditions.

    While it's possible to handle this entirely within Storyline using triggers and conditions, the solution becomes clunky and difficult to scale if you have more than four variables. You would also end up with too many triggers, making it more complex to track and maintain. Additionally, this method introduces delays, as it relies on event-based triggers rather than true loops or real-time logic.

    However, there's a cleaner workaround using a small JavaScript snippet. JavaScript can efficiently handle loops and ensure unique number generation and you can still pass those values back into Storyline variables. Let me know if you'd like help setting that up.

  • HoneyTurner's avatar
    HoneyTurner
    Community Member

    The trick to continuous loops is using toggle. If valueB is good, toggleC, else toggleB again. 
    But, it's much easier to do this task using javascript. 

    I made a row of 4 circles and displayed a variable in each: %circleA%, %circleB%, etc. These variables were text, so the same solution would work if you were randomizing fruit names or anything else.

    Then attach this javascript either on page load or button click.

     

    // Define your list as a JavaScript array
    var myList = ["1", "2", "3", "4"];

    // Fisher-Yates Shuffle Algorithm
    for (let i = myList.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [myList[i], myList[j]] = [myList[j], myList[i]]; // Swap elements
    }

    // Update Storyline variables
    var player = GetPlayer();

    player.SetVar("circleA", myList[0]);
    player.SetVar("circleB", myList[1]);
    player.SetVar("circleC", myList[2]);
    player.SetVar("circleD", myList[3]);

     

  • JavaScript is more elegant and efficient, but for a few variables, you can do it with a handful of triggers on a layer.

    Demo: https://360.articulate.com/review/content/041f67c6-c44a-47e8-a301-632caa78772b/review

    This just shows a layer that assigns 4 random numbers to 4 variables. If any are the same, it reruns the the layer until they are all unique. This is very brute-force, but very simple. The triggers are fast enough that even if it takes many attempts, it is still practically instant.

    This could be modified with a few more triggers to be more elegant, recalculating each random number only if it matches one of the previous variables, but in the end it is essentially the same thing. Simple gets the job done.

    As Nedim mentioned, if you try this with many variables, it could begin to slow down, or require too many triggers. In that case, JavaScript is the way to go. 

    • Nathan_Hilliard's avatar
      Nathan_Hilliard
      Community Member

      As an interesting aside, you can reliably generate about 6 randomized variables this way. Speed, however, doesn't seem to be the problem for additional entries.

      It appears that the iterations generally cap somewhere between the mid-200s and mid 300s. There may be some kind event buffer that maxes-out, and any further trigger events generated in this loop-like structure are ignored. 

      Possibly a useful tidbit for future troubleshooting of complex trigger setups.

  • Nedim's avatar
    Nedim
    Community Member

    Actually, you can simulate your own “loop” in Storyline to keep generating random values for A, B, C, and D until they are all unique by using a motion path animation as a timer:

    1. Insert a small shape (call it interval) and create a short motion path animation for it, lasting between 0.1 and 1 second (eg., 0.5)
    2. Start moving interval along its motion path when the learner clicks a button.
    3. Set a trigger to move interval again along the same path whenever the animation completes.
    4. This creates a continuous loop effect, running every 0.5 second depending on the animation length.
    5. On each animation completion, add separate triggers to assign random numbers between 1 and 4 to A, B, C, and D.
    6. Also on animation completion, check if A, B, C, and D are all unique. If they are, stop (hide) the interval to end the loop.

    To rerun the process, create a trigger that resets the state of interval to Normal when the learner clicks a button, which restarts the animation and loop.

    This solution only requires about six triggers in total, far fewer than I originally expected, and it doesn’t rely on any JavaScript or additional layers.

    Edit:
    This motion path trick is conceptually similar to running this JavaScript code, though not identical. JavaScript offers more precise and consistent timing compared to motion path animations in Storyline.

    const interval = setInterval(() => {
      const A = getVar("A");
      const B = getVar("B");
      const C = getVar("C");
      const D = getVar("D");
    
      const values = [A, B, C, D];
      const unique = new Set(values);
    
      if (unique.size === 4) {
        clearInterval(interval);
      }
    }, 500);
    

     

  • I really appreciate all the assistance on this. Both in Javascript and via triggers. Thank you all for helping me out on this.

    • Nedim's avatar
      Nedim
      Community Member

      No problem at all! You actually inspired me to create a few different versions of this using both triggers alone and JavaScript. Here's one more version — just for the record and for others who might find this discussion useful. This version introduces a slight delay between each number’s appearance, while still ensuring all numbers have unique values.