Dynamic Arrays - Epic Wiki
# Dynamic Arrays
# Contents
- 1 Overview
- 2 Available Types
- 3 Arrays of USTRUCTS() or Pointers to UStructs
- 4 Blueprint-Accessible Dynamic Arrays
- 5 Core Functions
- 6 For Loops
- 7 Index Safety Check To Prevent Crashes
- 8 Awesome Functions
- 9 Min/Max of Array (4.3 and higher)
- 10 Multi Dimensional Arrays
- 11 [Epic Docs] TArray Optimization Techniques
- 12 Summary
# Overview
Dear Community,
Here is my introduction to UE4 C++ Dynamic Arrays!
They're awesome!
# Example 1
You can use dynamic arrays to store references to every ACharacter that crosses a certain point in your level, and then, after at least 5 ACharacters have crossed the point, you can iterate over all the actors and perform an action.
So in this way, you could make it a game-ending condition that if 5 bunny-rabbits reach their home, then the game ends in success.
During runtime you never know how long it will take for the bunny-rabbits to reach home, but via code you can track how many have reached home, whenever they do, and the iterate over all of them to make them perform some kind of victory dance as the level ends.
But you also never know which bunny-rabbits will be doing the dancing!
thus the word "dynamic"
Dynamic arrays enable you to track dynamically changing game conditions from the UE4 C++
# Example 2
You could make a dynamic array that is accessible to blueprints so your team members working in blueprints can add information to the dynamic array, which you as the programmer will then use in c++ during runtime.
But you as the programmer do not know how much data they will add!
So you could give the level designers a dynamic array to edit in blueprints, and they will fill it with 3 or 10 or 100 level names.
Then you can, in the C++, iterate over all of the level names and display them, without ever knowing in advance how many levels the designers added!
And the level designers can add more any time!
# Summary
Dynamic arrays are one of the most essential tools for any game-logic that you want to do,
where the actions of the player, the in-game AI, and the rest of your team cannot be known in advance,
but need to be tracked, organized, and facilitated via UE4 C++ code systems.
# Available Types
- Any C++ type
- Any UE4 C++ type, such as FLinearColor
- Pointer to a UObject or an AActor extending class
- Pointer to Blueprint Classes
- UE4++ Enums
- USTRUCTS() or USTRUCT() pointers
# C++ Type
TArray<uint8> BinaryArray;
# UE4 C++ Type
TArray<FRotator> StarLocations;
# Pointer to UObject Class
TArray<USkeletalMeshComponent*> Weapons;
# Pointer to AActor Class
TArray<ACharacter*> FrogsThatAreHopping;
# Pointer to Blueprint Class
TArray<UClass*> FlowerBlueprints;
# UE4 C++ Enums
TArrayEKeys::Type\ GameControlKeys;
# Arrays of USTRUCTS() or Pointers to UStructs
Let's say you have defined this USTRUCT()
# Sample USTRUCT()
USTRUCT() struct FFlowerStruct { GENERATED_USTRUCT_BODY() UPROPERTY() int32 NumPetals; UPROPERTY() FLinearColor Color; UPROPERTY() FVector Scale3D; void SetFlowerColor(const FLinearColor& NewColor) { Color = NewColor; } FFlowerStruct() { NumPetals = 5; Scale3D = FVector(1,1,1); Color = FLinearColor(1,0,0,1); } };
# Array of USTRUCTS()
You can make an array of FFlowerStructs as follows!
TArray<FFlowerStruct> Flowers;
# The Pointer Version
TArray<FFlowerStruct*> FlowerPtrs;
# Blueprint-Accessible Dynamic Arrays
/** Add entries in BP Defaults, or during Runtime! Iterate over them using the For Each Loop BP Node */ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Flowers") TArray<FName> FlowerNames;
# Core Functions
# .Add()
TArray<FVector> StarLocations; StarLocations.Add(FVector(0,0,2000000));
# .Remove()
//Defined in the .h file: // TArray<ACharacter*> FrogsThatAreHopping; // ACharacter* FrogThatIsTired; FrogsThatAreHopping.Remove(FrogThatIsTired);
# .RemoveAt()
//Remove first frog from the array if(FrogsThatAreHopping.Num() > 0) { FrogsThatAreHopping.RemoveAt(0); }
# .Num()
Returns number of elements in the array (can be used when you need the length of the array).
ClientMessage("Total Flower Count"); ClientMessage(FString::FromInt(Flowers.Num()));
# For Loops
# Basic
// defined in .h TArray
# For AActor*
I am including very rigorous pointer safety and AActor validity checks,
because you dont want your whole game to crash to desktop, ever 😃
//defined in the .h : TArray<AFlower*> Flowers; //Print out each flower's UE4 Name AFlower* CurFlower = NULL; for(int32 b = 0; b < Flowers.Num(); b++) { CurFlower = Flowers[b]; if(!CurFlower) continue; if(!CurFlower->IsValidLowLevel()) continue; //~~~~~~~~~~~~~~~~~~~~~~ ClientMessage(CurFlower->GetName()); }
# Using Iterator
Posted originally by Solid Snake, thanks Solid Snake!
for (auto Iter(TArray.CreateIterator()); Iter; Iter++) { // *Iter to access what this iterator is pointing to. }
# Iterator AActor* Example
//defined in the .h : TArray<AFlower*> Flowers; //Print out each flower's UE4 Name for (auto Itr(Flowers.CreateIterator()); Itr; Itr++) { if(!(*Itr)->IsValidLowLevel()) continue; //~~~~~~~~~~~~~~~~~~~~~~ ClientMessage((*Itr)->GetName()); }
# Abbreviated C++11 Syntax
This one is great when you don't need to know the index as you are iterating! Rama (talk)
this:
for(int32 b; b < StarLocations.Num(); b++) { ClientMessage(StarLocations[b].ToString()); }
becomes this:
for(const FVector& EachLocation : StarLocations) { ClientMessage(EachLocation.ToString()); }
If you want to change the value in the loop, and not just read it, then remove the const 😃
# Index Safety Check To Prevent Crashes
# .IsValidIndex()
//defined in .h
//TArray
# Awesome Functions
# .Empty()
Empty array of all current contents
//It's nighttime, no more hopping; FrogsThatAreHopping.Empty();
# .Append()
Add the entire contents of one array to the end of another!
TArray<FVector> StarLocations; TArray<FVector> CloudLocations; TArray<FVector> StarAndCloudLocations; StarLocations.Add(0,0,200000); CloudLocations.Add(50,25,11000); CloudLocations.Add(50,25,22200); StarAndCloudLocations.Append(StarLocations); StarAndCloudLocations.Append(CloudLocations); //Print out all Locations for(int32 b; b < StarAndCloudLocations.Num(); b++) { ClientMessage(StarAndCloudLocations[b].ToString()); }
# Min/Max of Array (4.3 and higher)
I offered two Math Library functions to Epic which are now part of the Engine in 4.3, allowing you to get the Min/Max of a Dynamic Array of any datatype for which the operator< is defined!
Full details here:
# Multi Dimensional Arrays
To make a 2 or higher dimensional array,
wrap the array in a UStruct, and then make an Array of the UStructs
# .H
USTRUCT() struct FFlowerField { GENERATED_USTRUCT_BODY() UPROPERTY() TArray<FFlowerStruct> Flowers; FFlowerField() { } }; //All Flower Fields on The Island TArray<FFlowerField> FlowerFields;
# .CPP
Then to Access a single Flower
//Is there at least 1 Flower Field? if(FlowerFields.Num() > 0) { //Does the first field have at least 3 flowers? (could use .Num() too) if(FlowerFields[0].Flowers.IsValidIndex(2)) { //Number of petals on the 3rd flower in 1st field ClientMessage(FString::FromInt(FlowerFields[0].Flowers[2].NumPetals)); } }
# Full 2D Array Code Sample
I have two extensive code samples for how to make 2D arrays that are BP-friendly and can be replicated!
My Fully Coded 2D Array Example
Replicating BP-Friendly 2D Array
# [Epic Docs] TArray Optimization Techniques
Epic has posted an awesome article on ways you can optimize your use of TArray!
TArray Optimizations for Performance
# Summary
I hope you have enjoyed my description of UE4 C++ Dynamic Arrays!
Enjoy!
Retrieved from "https://wiki.unrealengine.com/index.php?title=Dynamic_Arrays&oldid=14756"