x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

How to Access a BP Script array (FScriptArray) and members from C++ ?

Dear Friends at Epic,

Suffice it to say that it is a project specification that I must access a BP array from C++.

So context:

I have a blueprint

this blueprint has a dynamic array of FNames.

I want to access this array, its total, and its members from c++

I am not instancing this blueprint into the world, the array values are set in its defaults only.


Here's as far as I got:

 //Get BP Array, returns total count
 static FORCEINLINE int32 GetBPArray( UClass* TheBP, const FName& Name)
 {
     if(!TheBP)             return -1;
     if(Name == NAME_None)     return -1;
     //~~~~~~~~~~~~~~~
         
     UArrayProperty* ArrayProp = FindField(TheBP, Name);
     FScriptArray* ScriptArray = ((FScriptArray*)ArrayProp);
     if(ArrayProp != NULL && ScriptArray )
     {
         FScriptArrayHelper BPArrayHelper(ArrayProp,ScriptArray->GetData());
         return BPArrayHelper.Num();
     }
         
     return -1;
 }


The **FScriptArrayHelpe**r returns garbage even though there are actually 4 array entries set in the default.

if I use this version

 return ScriptArray->Num();

it returns 1, but there are actually 4 default entries :)


Any ideas?


And Accessing Members?

I still have very little idea of how to access the members of this ScriptArray, even if I can get the count correctly :)

Thanks!

Rama

PS: Yes, I know it would be easier/better/faster/more efficient to have the array in C++, I know, please read the first line, :)

Product Version: Not Selected
Tags:
more ▼

asked Mar 11 '14 at 02:43 AM in C++ Programming

avatar image

ue4-archive ♦♦ STAFF
49.9k 3658 1983 9111

(comments are locked)
10|2000 characters needed characters left

1 answer: sort voted first

I'm not the expert on this, but you need to do some massaging of the data before you can use it and FScriptArray is not what you want, although FScriptArrayHelper is. You want to operate on the default object, not the class, although you will need the class too. I believe this is right, but I know you'll fiddle with it and let me know :)

 MyUObjectType* Object = MyClass->GetDefaultObject();
 UArrayProperty* ArrayProp = FindField(MyClass, Name);
 
 // Your data is inside a UObject, it needs to be accessed appropriately
 FScriptArrayHelper_InContainer ArrayHelper(ArrayProp, Object);
 
 FString Value;
 for( int32 i=0; iInner->ExportTextItem( Value, ArrayHelper.GetRawPtr(i), ArrayHelper.GetRawPtr(i), Obj, PPF_IncludeTransient );
 }
more ▼

answered Mar 11 '14 at 02:43 AM

avatar image

ue4-archive ♦♦ STAFF
49.9k 3658 1983 9111

avatar image ue4-archive ♦♦ STAFF Mar 11 '14 at 02:43 AM

Woohoo!

Great to hear from you Josh!

Yea I knew I wasnt using the Helper right, I will try out what you have here!

// Your data is inside a UObject, it needs to be accessed appropriately FScriptArrayHelper_InContainer ArrayHelper(ArrayProp, Object);

And I had no idea about the string stuff

Thanks for the Code Josh!

Rama

avatar image ue4-archive ♦♦ STAFF Mar 11 '14 at 02:43 AM

For Your Entertainment Josh

For your entertainment Josh,

I have now posted a tutorial on how to access BP Arrays in C++, and also retrieve the type of the array as well as all the data!


I am posting pics and code here for future readers and for you to enjoy Josh!


I post code for converting Int, Float, and Vector BP arrays into their C++ TArray equivalents.

My Test BP Extend AActor

I ran my tests on a blueprint that was extending the very base class of AActor itself!

Yay!

Thanks for Your Help!

Tutorial on Accessing BP-created Arrays in C++

ttp://forums.epicgames.com/threads/972861-43-TUTORIALS-C-for-UE4-gt-gt-New-How-to-Access-a-Blueprint-Created-Array-From-C?p=31799080#post31799080

Pics

alt text

alt text

Enjoy!

avatar image ue4-archive ♦♦ STAFF Mar 11 '14 at 02:43 AM

C++ Code

 //Get BP Array, returns total count
 static FORCEINLINE int32 GetBPArray( UObject* Obj, const FName& Name, FString& CPPMacroType,TArray& OutData)
 {
     if(!Obj)             return 0;
         if(!TheObj->IsValidLowLevel()) return 0;
     if(Name == NAME_None)     return 0;
     //~~~~~~~~~~~~~~~
     
     UArrayProperty* ArrayProp = FindField(Obj->GetClass(), Name);
      
     // Your data is inside a UObject, it needs to be accessed appropriately
     if(ArrayProp != NULL)
     {
         FScriptArrayHelper_InContainer ArrayHelper(ArrayProp, Obj);
         
         //Get the Array Type!!!
         ArrayProp->GetCPPMacroType(CPPMacroType);
         
         //Get FString Array of the Data
         FString Value;
         for( int32 i=0; iInner->ExportTextItem( Value, ArrayHelper.GetRawPtr(i), ArrayHelper.GetRawPtr(i), Obj, PPF_IncludeTransient );
             
             //Add
             OutData.Add(Value);
         }
 
         return ArrayHelper.Num();
     }
     
     return 0;
 }

Converting from FString Array to C++ Equivalent

 void AMyBasePlayerController::GetBPArrayData(UObject* TheObj, const FName& ArrayName)
 {
     if(!TheObj) return;
         if(!TheObj->IsValidLowLevel()) return;
     //~~~~~~~~~~~~~~~~
     
     FString BPArrayType = "";
     TArray StrVersionOfData;
     
     const int32 ArrayTotal = 
         UCoreFunctions::GetBPArray(TheObj, ArrayName,BPArrayType,StrVersionOfData);
     
     
     //Output
     FString Str = "";
     Str = FString::FromInt(ArrayTotal);
     ClientMessage(Str);
     
     ClientMessage("Array Type");
     ClientMessage(BPArrayType);
     
     //Is BP Array FName Array?
     if(BPArrayType == "FName")
     {
         TArray TheNames;
         for(int32 v = 0; v < ArrayTotal; v++)
         {
             TheNames.Add(*StrVersionOfData[v]);
         }
         
         //Display FName Array
         ClientMessage("This is the actual FName Array now");
         for(int32 v = 0; v < ArrayTotal; v++)
         {
             ClientMessage(TheNames[v].ToString());
         }
     }
     
     //Is BP Array Int Array?
     if(BPArrayType == "Int")
     {
         TArray TheInts;
         for(int32 v = 0; v < ArrayTotal; v++)
         {
             TheInts.Add(FCString::Atoi(*StrVersionOfData[v]));
         }
         
         //Display Array
         ClientMessage("This is the actual int Array now");
         for(int32 v = 0; v < ArrayTotal; v++)
         {
             ClientMessage(FString::FromInt(TheInts[v]));
         }
     }
     
     //Is BP Array Float Array?
     if(BPArrayType == "Float")
     {
         TArray TheFloats;
         for(int32 v = 0; v < ArrayTotal; v++)
         {
             TheFloats.Add(FCString::Atof(*StrVersionOfData[v]));
         }
         
         //Display Array
         ClientMessage("This is the actual float Array now");
         for(int32 v = 0; v < ArrayTotal; v++)
         {
             ClientMessage(FString::SanitizeFloat(TheFloats[v]));
         }
     }
     
     //Is BP Array Vector Array?
     if(BPArrayType == "FVector")
     {
         TArray TheVectors;
         for(int32 v = 0; v < ArrayTotal; v++)
         {
             FVector NewVector;
             NewVector.InitFromString(StrVersionOfData[v]);
             TheVectors.Add(NewVector);
         }
         
         //Display Vector Array
         ClientMessage("This is the actual Vector Array now");
         for(int32 v = 0; v < ArrayTotal; v++)
         {
             ClientMessage(TheVectors[v].ToString());
         }
     }
 }


(comments are locked)
10|2000 characters needed characters left
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question