Basic Scripting Question: How to access one element of an array by index, and print it?

12/15/22 Update: Thanks @KyleDev for the answer and explanation!

Kyle explained the snippet from the docs that was confusing me. I’m summarizing the convo here or you could also read the comments for more info:

The snippet from the docs:

for (Index := 0..MyArray1.Length-1):
    if (Element := MyArray1[Index]):
        Log("{Element} in MyArray1 at index {Index}")

This loops through the array, printing the element and the index of the array to the log. (Side not, for me Log doesn’t work and I need to either use Logger.Print or Print)

Within (Index := 0…MyArray1.Length-1):, Index := 0 signifies the first element in the array, and MyArray1.Length-1 signifies the last element of the array. The -1 is because in Verse the index starts at 0 instead of 1.

If I want to print a specific element of the array I can specify the index like this:

   OnBegin<override>()<suspends>:void=
        Logger.Print("Array_Test device started")
        for (Index := 0..MyArray1.Length-1):
            if (Element := MyArray1[1]):
                Logger.Print("{Element}")

In MyArray[1], the number 1 is the index of the element I want to print. Technically this will be the second element in my list not the first, because the index starts with 0.

A separate issue is that in my initial code I should have written Print({Element}) instead of Print("{Element}") Oops. Ended up using Logger.Print instead of Print anyway the Print() text disappears too fast.

Also, the script does print Element 2 three times in a row, instead of once, so I still want to figure out why that is and how to change it. I tried adding an else statement but then my script broke and I need to take a break before trying again.

===========================================================================================================================

12/15/22 Original Question:

Hey, so this should be extremely simple but I’m having a hard time understanding the Verse documentation on arrays. Thanks in advance for the help!

For my dialogue script with Verse UI, I want editable arrays of strings that I can change from the details panel. Similar to the editable array setup in @HugoMeta4 's subtitle system but I’m starting simple. All I need right now is to grab strings from the elements in my editable array, by index, and print them in the UI widget. I don’t need help with UI API atm, because I already learned how to create and edit the widgets, studying Hugo and @RayBenefield 's snippets.

This is a test I tried, which is wrong:


    @editable MyArray1: []string = array{}

    OnBegin<override>()<suspends>:void=
        Print("Array_Test device started")
        for(Element, MyArray1)
            if(Element := MyArray1[1]):
                Print("hi")

I understand from the docs that in order to access elements from arrays I need to be in a failure context, so I tried putting things in an if statement but I’m confused.

I get an error after print saying: “Expected expression or “)”, got “{” in parenthesized parameter list”

So then I tried Printing just (“hi”) and I see an error saying " Can’t use built-in macros other than to invoke them."

The examples in the docs for Arrays, and in the snippets from the Snippet Repository are more complicated than what I want to do, and I can’t yet figure out how to adapt the code for my case. :confused: https://dev.epicgames.com/documentation/unreal-editor-fortnite/en/0Jpo/Verse/array-in-verse

Thanks! :slightly_smiling_face:

Sneak peek at the dialogue system this is for:


The pink text box is actually a translucent material on an inverted box, which is stuck to the screen, using Disable Depth Test setting and adding a ScreenPosition node. Learned that from @Rynex_FNC ! I’ll explain more about the material in my Sprigs devlog and post a snippet once my system is cleaned up enough to share.

It’s gonna be so cool, I want my snippet to be super usable for beginners.
Also Taylor Swift is not in my game lol I just always use her lyrics for lorem ipsum.

Here is an snippet of how you would loop through an array outputting both the element and index of the array to the log:

for (Index := 0..MyArray1.Length-1):
    if (Element := MyArray1[Index]):
        Log("{Element} in MyArray1 at index {Index}")

Thanks for the help! I saw that snippet in the docs section about arrays and I tried it and was able to print out a list of all of my elements in my array. But I didn’t understand it. Specifically this part: (Index := 0..MyArray1.Length-1): What is the -1 for?

Now that you’re saying it loops through the elements in the array I understand it better. The docs actually don’t explain that. In Lua I’ve looped through tables, which I think are similar to arrays.

What if I don’t want to to print out all of the elements in a list like the example does? I only want to specify one of them? I’m going to experiment some more, now that I think I have a better grasp of what that snippet from the docs does.

Also noticing that in my initial code that I posted here, I should have written (“{Element}”) instead of ({Element}). Oops :laughing:

Oh cool, @KyleDev , I figured it out partly!!!

I did this:


OnBegin<override>()<suspends>:void=
        Print("Array_Test device started")
        for (Index := 0..MyArray1.Length-1):
            if (Element := MyArray1[1]):
                Logger.Print("{Element}")

However it does print Element2 in the logger three times instead of one. Probably because of the way it’s looping through everything in the array. It must be printing Element 2 every time it hits an element in the loop. There are three elements in the array. \

Actually I’m pretty sure I tried this exact code a while ago but I was using Print({Element}) instead of Print("{Element}"). So the array part wasn’t wrong, my syntax after Print was wrong.

Sure, if you only want to print one of the values stored in the array then you would still need to loop through the array but instead of printing every iteration you can specify which by changing the index.

The reason for the -1 is because arrays are zero indexed - an array with n elements is indexed from 0 to n-1.
This means arrays count from 0, so the first number = 0 , second number = 1 and the last number is the last number -1 … The first (for) line is saying to count from 0 to … the length of the array, therefore counting all of the values in the array.

I’m sure someone else can explain better but I hope that helps :slightly_smiling_face:

Ohhh ok that does make sense! So the two dots mean from x to x, like the two dots are the “to”? Index :=0 is the beginning of the array, and MyArray1.Length-1 is the end of the array. The function loops through all of those elements in the array. For every element, if that element is MyArray1[1] it prints the the string that I chose for that element?

Instead of printing out a list of all of the elements, now it prints a list of three elements, but every element is Element2.
image

I tried adding an else statement to see what would happen. but now the logger is printing nothing, so I guess I messed it up. I also have two scripts I’ve been testing so maybe I messed the other one up. :woman_shrugging:

   OnBegin<override>()<suspends>:void=
        Logger.Print("Array_Test device started")
        for (Index := 0..MyArray1.Length-1):
            if (Element := MyArray1[1]):
                Logger.Print("{Element}")
            else:
                Logger.Print("")

Dang, my Array_Test script broke and it won’t even print anything On Begin, even before any of the rest of the script. Not sure what I did to break it!

I thought maybe it was because of some changes I made to a different script, so I commented out that whole other script, but my Array_Test script is still broken. Even though to me it looks exactly the same as the version of it that was working before. I’ll have to take a break and return to it later. Maybe I’ll just start another script from scratch, or even start another project from scratch.

Does any of this look wrong to anyone?

using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /EpicGames.com/Temporary/Diagnostics }

log_Array_Test := class(log_channel){}

Array_Test := class(creative_device):
    Logger:log = log{Channel:=log_Array_Test}

    @editable MyArray1: []string = array{}

    OnBegin<override>()<suspends>:void=
        Print("Array_test device startedt")
        Logger.Print("Array_Test device started")
        for (Index := 0..MyArray1.Length-1):
            if (Element := MyArray1[1]):
                Logger.Print("{Element}")

@KyleDev did answer my question about Arrays though! I was able to get the script to work, before it broke for an unknown reason.

Hi @Fresnella, I took a look at your script and tried it as-is, which gives me the following printed output when I start the game with a single Array_Test device in the level:

LogVerse: : Array_test device startedt
LogVerse: log_Array_Test: Array_Test device started

If you’re trying to print out the individual elements, you can use a different syntax for iterating over the elements of an array in Verse:

        for (Element : MyArray1):
            Logger.Print("Hi I'm an {Element}")

When I do this and I have a few elements filled in the Array_Test device, I get:

LogVerse: : Array_test device startedt
LogVerse: log_Array_Test: Array_Test device started
LogVerse: log_Array_Test: Hi I'm an foo
LogVerse: log_Array_Test: Hi I'm an bar
LogVerse: log_Array_Test: Hi I'm an baz

Let us know if that works for you, or if you’re still not seeing any output in the Output Log.