Arrays (Papyrus)

From the Fallout4 CreationKit Wiki
Jump to navigation Jump to search

Description[edit | edit source]

Arrays are special kinds of variables that can hold more then one value of the same type. You select which value you want via a numerical index that ranges from zero to the length of the array, minus one. More information on arrays can be found on the Array Reference.

Declaring Arrays[edit | edit source]

 float[] myFloatArray
 ObjectReference[] myObjectArray = new ObjectReference[10]
 Form[] myFormArray = new Form[myObjectArray.Length]

myFloatArray specifies an empty array of floats. It has a length of 0, and is equal to None. myObjectArray also starts that way, except it is an array of ObjectReference objects. It is then assigned a new array of ObjectReference objects, with 10 elements in it (all of which start with the default value of None). myFormArray is assigned a new array of Form objects, with the same number of elements as myObjectArray has.

The new call must be done inside a function. You cannot use it on an object variable outside of a function. If you want a variable to start with an empty array, then you can make the array inside the OnInit event.

Note that you cannot have an array of arrays, or a multi-dimensional array.

You can, of course, make an property that is an array. The editor will show a special UI for it that allows you to add, remove, and re-arrange the array items inside it.

Example:

 Weapon[] Property MyWeapons Auto

Function Parameters[edit | edit source]

To accept an array as a parameter to a function, use the same syntax as for declaring an array.

Example:

 Function MyArrayFunction(int[] myArray, bool someOtherParameter)
 EndFunction

Returning from Function[edit | edit source]

To return an array from a function, again, use the same syntax.

Example:

 int[] Function MyReturnArrayFunction()
   int[] someArray = new int[10]
   return someArray
 endFunction

Creating Arrays[edit | edit source]

To create an array, use the "new" keyword, followed by the array's element type, and the size of the array in brackets. Arrays can be any size, up to 128 elements. Attempting to create an array larger then that will fail. Every element in the array will be set to the element's default value, be that 0, false, "", or None.

Note that if you create a new array of a type that extends ScriptObject or a struct that all the elements in the array will be None. In the case of structs, you will have to then either fill the items with structs from somewhere else, or by calling new on each element. For items that extend ScriptObject you'll have to get the items from somewhere else (like a function call or a filled property)

Example:

 new bool[5] ; Array of 5 Booleans, all set to False
 new Weapon[numWeapons + 2] ; Array of weapons, all set to None
 new MyStruct[10] ; Array of MyStruct, all set to None

Usually you'll be assigning these directly to new array variables, but if a function wants an array, you can make the new array in the function call, like so:

Example:

 MyArrayFunction(new int[20])

Getting/Setting Elements[edit | edit source]

To get a single value from an array, or to set it, use brackets with the index of the element you want between them after the variable name. The index can be an integer variable, raw integer, or the result of an expression. The range of valid values is from 0 (for the first element) to the length of the array, minus 1.

Example:

 myArray[20] = newValue
 someRandomValue = myArray[currentIndex]
 myArray[i * 2] = newValue

If the array elements are other scripts, you can access properties and functions in the same way.

Example:

 DoorArray[currentDoor].Lock()
 objectXPos = ObjectArray[currentObject].X

Note that, since arrays are passed and assigned by reference, that any modifications to an array's elements will be reflected in any other variables looking at that array.

Getting Length[edit | edit source]

You can easily get the length of any array by calling the length property on it. If you assign None to an array, the length will be 0.

Example:

 int ArrayLength = myArray.Length

Assigning/Passing Arrays[edit | edit source]

Assigning one array to another array, or passing an array to a function, is done just like any other variable. However, note that arrays are passed/assigned by reference, just like objects. In other words, if you assign one array to another, both are looking at the same array - and modifications made to one, will be reflected in the other.

Example:

 int[] Array1 = new int[5]
 int[] Array2 = Array1     ; Array1 and Array2 now look at the same array!
 Array1[0] = 10
 Debug.Trace(Array2[0])    ; Traces out "10", even though you modified the value on Array1

Casting Arrays[edit | edit source]

Arrays can to strings, or bools, as well as to another array type if the elements themselves would cast. If you cast an array to a string, it will put each element in the array inside brackets, separated by commas. If the array is especially long, it may trim the string a little early and put an ellipsis on the end. If you cast an array to a bool, it will be true if the length is non-zero, and false if the length is zero. If you cast an array to another array type, the array will be duplicated and the elements cast to the desired type. Any elements that fail to cast will be left as 0, None, or an equivalent. For example, if you cast a Form array to an ObjectReference array, any elements in the Form array that are not actually ObjectReferences will be empty in the duplicate created.

Example:

 Debug.Trace(MyArray)    ; Traces out "[element1, element2, element3]" or "[element1, element2, ...]" if the array is too large
 if (MyArray)
   Debug.Trace("Array has at least one element!")
 else
   Debug.Trace("Array has no elements!")
 endIf


 ObjectReference[] myObjRefArray = new ObjectReference[10]
 ; .. fill array here
 Form[] myFormArray = myObjRefArray as Form[]
 ; myFormArray points at a copy of myObjRefArray with the elements cast
 ; modifying myFormArray will not affect myObjRefArray

Searching Arrays[edit | edit source]

Arrays can be searched using two different methods, called "find" and "rfind". Find searches the array from the element you give it (default is element 0) and goes forward through the array to the final element, or the first match it finds, whichever is first. RFind does the same thing, only backwards, starting at the element you give it (default is -1, which means the last element) and going towards element 0. If the item is not found, it will return a negative number for the index.

Examples:

; Set up an array for the example
string[] myArray = new string[5]
myArray[0] = "Hello"
myArray[1] = "World"
myArray[2] = "Hello"
myArray[3] = "World"
myArray[4] = "Again"

; Prints out "Whee! does not exist in the array"
if myArray.Find("Whee!") < 0
  Debug.Trace("Whee! does not exist in the array!")
else
  Debug.Trace("Whee! exists in the array!")
endIf

; Prints out "The first Hello is at position 0"
Debug.Trace("The first Hello is at position " + myArray.Find("hello"))

; Prints out "The last Hello is at position 2"
Debug.Trace("The last Hello is at position " + myArray.RFind("hello"))

; Prints out "The first Hello in or after position 2 is at position 2"
Debug.Trace("The first Hello in or after position 2 is at position " + myArray.Find("hello", 2))

If you want to search an array of structs for a struct with a particular value, you can do so with the FindStruct and RFindStruct functions. They work identically to find and rfind, except the first parameter is the name of the struct value to look for.

Examples:

Struct Point
  int X
  int Y
EndStruct

Function MyFunction()
  Point[] myArray = new Point[2]

  Point myPoint = new Point
  myPoint.X = 1
  myPoint.Y = 2
  myArray[0] = myPoint

  myPoint = new Point
  myPoint.X = 10
  myPoint.Y = 11
  myArray[1] = myPoint

  ; Prints "The point with an X value of 1 is at 0"
  int index = myArray.FindStruct("X", 1)
  Debug.Trace("The point with an X value of 1 is at: " + index)
EndFunction

See Also[edit | edit source]

Adding Items[edit | edit source]

You can add items to an array using Add or Insert. Note that you are still restricted to the array size limit listed above. Add takes an optional count parameter which adds that many items to the array, though in the case of adding structs, they will all point at the same struct rather then making struct copies.

Examples:

; Add the numbers 0 through 4 to the array as strings
string[] MyArray = new string[0]
int currentItem = 0
while (currentItem < 5)
  MyArray.Add(currentItem as string)
  currentItem += 1
endWhile

; Array is now: ["0", "1", "2", "3", "4"]

; Add 2 copies of "Hello" to the array
MyArray.Add("Hello", 2)

; Array is now: ["0", "1", "2", "3", "4", "Hello", "Hello"]

; Insert "World" into index 1 (second position)
MyArray.Insert("World", 1)

; Array is now: ["0", "World", "1", "2", "3", "4", "Hello", "Hello"]

See Also[edit | edit source]

Removing Items[edit | edit source]

You can likewise remove items from the array using RemoveLast, Remove (which can take a count of items to remove), and Clear. Note that the items are completely removed from the array, and items later in the array are compacted down.

Examples:

; Assuming we're starting with the array from the add examples:
; ["0", "World", "1", "2", "3", "4", "Hello", "Hello"]

MyArray.RemoveLast()

; Array is now: ["0", "World", "1", "2", "3", "4", "Hello"]

MyArray.Remove(0)

; Array is now: ["World", "1", "2", "3", "4", "Hello"]

MyArray.Remove(2, 3)

; Array is now: ["0", "World", "1", "Hello"]

MyArray.Clear()

; Array is now: []

See Also[edit | edit source]

Common Tasks[edit | edit source]

Doing Something to Every Element[edit | edit source]

Frequently you may want to do something to every element in an array. This is easily done by setting up a while loop with a counter, and then doing something to each element, like so:

Example:

 Function DisableAll(ObjectReference[] objects)
   int currentElement = 0
   while (currentElement < objects.Length)
     objects[currentElement].Disable()
     currentElement += 1
   endWhile
 EndFunction

Note that the while loop will go as long as the element is less than the length of the array. This is because the valid elements are zero to length minus one. If you were to make a while loop using "<=" you would error on the last element, because you would be trying to get an element one past the end of the array.

Counting Certain Elements[edit | edit source]

Sometimes you might want to count how many of X is in an array. You can do this with Find and a while loop, making sure that each find starts at one after the location where the previous find located an element. Make sure it is one past the previous location, otherwise you'll get stuck looking at the same one every time.

Example:

; Counts the number of hellos there are in the array
int currentPosition = myArray.Find("hello")
int count = 0
while currentPosition >= 0 ; Loop until we don't find any more (position is less then zero)
  count += 1
  currentPosition = myArray.Find("hello", currentPosition + 1) ; +1 so we don't find the same one again
endWhile

Debug.Trace("There are " + count + " hellos in the array")